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