UDP介紹及UDP傳送端和接收端廣播程式碼

Jiangson發表於2024-06-07

目錄
  • UDP介紹
  • UDP特點
    • 無連線:
    • 不可靠性:
    • 高效性:
    • 實時性:
    • 廣播和多播:
    • 資料包大小限制:
    • 簡單性:
  • UDP實現廣播的程式碼思路
    • 傳送端
    • 接收端

UDP介紹

UDP(User Datagram Protocol,使用者資料包協議)是一種無連線的、不可靠的傳輸層通訊協議,它在OSI模型的第四層,即傳輸層中執行。UDP設計簡單,不提供資料包分組、組裝和排序,因此它不保證資料傳輸的可靠性和順序性,但它的優點是傳輸速度快,延遲低,適合實時性要求高、允許一定資料丟失的應用場景。可以用於影片、語言、音訊等傳輸。

UDP特點

無連線:

UDP在傳送資料之前不需要建立連線。這意味著傳送端可以在任何時候傳送資料包,而不需要預先通知接收端。這種無連線的特性使得UDP的開銷比TCP小,因為它不需要維護連線狀態。

不可靠性:

UDP不保證資料包的到達、順序或完整性。如果資料包在傳輸過程中丟失,UDP不會嘗試重新傳送。因此,使用UDP的應用程式需要自己處理資料包的丟失、重複或亂序問題。

高效性:

UDP的頭部開銷小,只有8位元組(即不傳送任何資料),而TCP的頭部至少有20位元組。這使得UDP在傳輸小資料包時更加高效。

實時性:

UDP適合實時應用,如線上遊戲、語音通話和視訊會議,這些應用通常可以容忍一定程度的資料丟失,但要求低延遲和快速的資料傳輸。

廣播和多播:

UDP支援廣播(向同一網路中的所有主機傳送資料)和多播(向一組特定的主機傳送資料),而TCP只支援點對點的通訊。

資料包大小限制:

UDP資料包的最大長度受限於IP協議,通常為65535位元組(包括UDP頭部和資料)。然而,實際網路中通常會有更小的MTU(最大傳輸單元)限制,因此資料包可能會被分片傳輸。

簡單性:

UDP協議簡單,易於實現和理解。它沒有複雜的握手過程、流量控制或擁塞控制機制。

UDP實現廣播的程式碼思路

傳送端

1.先socket建立套接字;2.用setsockopt設定套接字為廣播屬性;3.建立struct sockaddr_in xxx 結構體,把家族協議、埠號和廣播地址新增進結構體;4.用sendto傳送資料

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>

#define MSG_LEN 256
#define BROADCAST_ADDR  "192.168.xxx.255"

int main()
{
    int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd == -1)
    {
        perror("socket...");

        return -1;
    }
    int flag = 1;
    if(setsockopt(sock_fd,SOL_SOCKET,SO_BROADCAST,&flag,sizeof(flag))== -1)
    {
        perror("setsockopt...");
        return -1;
    }
    
    struct  sockaddr_in broadcast_inf;
    memset(&broadcast_inf,0,sizeof(broadcast_inf));

    broadcast_inf.sin_family = AF_INET;
    broadcast_inf.sin_port   = htons(8888);
    broadcast_inf.sin_addr.s_addr  = inet_addr(BROADCAST_ADDR);

    while(1)
    {
        char msg[MSG_LEN] = "You hao!";
        if(sendto(sock_fd,msg,strlen(msg),0,(struct sockaddr*)&broadcast_inf,sizeof(broadcast_inf)) == -1)
        {
            perror("sendto...");
            return -1;
        }
    }
   
   if(close(sock_fd) == -1)
   {
    perror("close...");
    return -1;
   }

   return 0;
}

接收端

1.socket建立套接字;2.建立結構體struct sockaddr_in xxx 填入自己的資訊用於繫結;3.用bind繫結套接字;4.recvfrom接收廣播的資訊

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>

#define MSG_LEN 256

int main()
{
    int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd == -1)
    {
        perror("socket...");
        return -1;
    }
     struct sockaddr_in own_inf;
     memset(&own_inf,0,sizeof(own_inf));

     own_inf.sin_family = AF_INET;
     own_inf.sin_port   = htons(8888);
     own_inf.sin_addr.s_addr = htonl(INADDR_ANY);

    //UDP需要bind才能接收    
     if(bind(sock_fd,(struct sockaddr*)&own_inf,sizeof(own_inf)) == -1)
     {
        perror("bind...");
        return -1;
     }

    char msg[MSG_LEN] = "\0";
     while(1)
     {
        
        if(recvfrom(sock_fd,msg,sizeof(msg),0,NULL,NULL) == -1)
        {
            perror("recvfrom...");
            return -1;
        }
        printf("%s\n",msg);

     }

    close(sock_fd);
    return 0;
}

相關文章