- 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;
}