UDP编程

UDP(User Datagram Protocol)是一种无连接的传输层协议,位于OSI模型的第四层。与TCP不同,UDP不提供可靠性保证、流量控制或拥塞控制机制,但具有低延迟和高效率的特点。

UDP的主要特性

无连接性

UDP在通信前无需建立连接,直接发送数据报。这减少了握手和断连的开销,但无法保证数据包的顺序或完整性。

不可靠传输

UDP不提供确认、重传或错误恢复机制。若数据包丢失或损坏,协议本身不会主动处理,需由应用层解决。

低开销

UDP头部仅8字节(包含源端口、目标端口、长度和校验和),远小于TCP的20字节头部,减少了传输负担。

支持广播和多播

UDP能够向多个目标同时发送数据包(广播或多播),适用于实时音视频、在线游戏等场景。

UDP的典型应用场景

  • 实时多媒体传输:如VoIP(语音通话)、视频会议(如Zoom部分使用UDP)。
  • 在线游戏:对延迟敏感的场景优先选择UDP,例如FPS游戏。
  • DNS查询:DNS协议默认使用UDP,快速解析域名。
  • IoT设备通信:传感器数据上报等轻量级通信。

UDP与TCP的对比

特性 UDP TCP
连接方式 无连接 面向连接
可靠性 不可靠 可靠(确认、重传)
传输效率 高(低开销) 较低(头部大)
数据顺序 不保证 保证按序到达
适用场景 实时应用、广播 文件传输、网页浏览

UDP的编程函数

在UDP中我们用到的函数如下

服务器端:

UDP编程常用函数

socket()

创建套接字,指定协议族(如AF_INET)和套接字类型(SOCK_DGRAM)。

复制代码
int socket(int domain, int type, int protocol);
bind()

将套接字绑定到本地IP地址和端口,通常用于服务器端。

复制代码
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sendto()

发送数据到指定的目标地址,适用于无连接的UDP通信。

cpp 复制代码
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);
recvfrom()

接收数据并获取发送方的地址信息,常用于服务器或客户端接收响应。

cpp 复制代码
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);
close()

关闭套接字释放资源。

cpp 复制代码
int close(int sockfd);

UDP客户端

socket()

sendto()

recevfrom()

close()

使用socket()创建套接字,使用UDP协议时,选择的SOCK_DGRAM,使用sendto()发送资源,由于UDP时无连接的,每次都要发送数据都需要指定对端的地址,recbform()接收数据,每次都需要传给该方法的一个地址结构存放发送端的地址,recvform()可以接收所有客户端发送给当前应用程序的数据,并不能接收一个客户端的数据.

UDP服务器代码

cpp 复制代码
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<arpa/inet.h>
#include<pthread.h>
int main(){
int sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(-1==sockfd)
{
exit(1);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(9999);
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
int n=bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr));
if(-1==n){
    printf("bind arror");
    exit(1);
}
while(1){
char buf[128]={0};
 int len=sizeof(saddr);
int n=recvfrom(sockfd,buf,127,
0,(struct sockarr *)&saddr,&len);
sendto(sockfd,buf,sizeof(buf)-1,0,(struct sockarr*)&saddr,sizeof(saddr));
if(n<0){
    break;
}
printf("%s",buf);
sendto(sockfd,"YES",3,0,(struct sockaddr *)&saddr,len);

}
close(sockfd);
}

UDP客户端代码

cpp 复制代码
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<arpa/inet.h>
int main(){
int sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(-1==sockfd)
{
exit(1);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(9999);
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
char buf[128]={0};
fgets(&buf,127,stdin);
int n=sendto(sockfd,buf,127,0,
    (struct sockaddr *)&saddr,sizeof(saddr));
 recvfrom(sockfd,buf , 127, 0,(struct sockaddr *)&saddr, sizeof(saddr));

        printf("buff = %s\n", buf); 
        close(sockfd);     

}
相关推荐
Lily.C2 小时前
小程序WebSocket实时通信全解析
websocket·网络协议·小程序
代码游侠2 小时前
学习笔记——TCP 传输控制协议
linux·网络·笔记·网络协议·学习·tcp/ip
ICT技术最前线2 小时前
华为交换机VLAN配置命令详解
服务器·网络·vlan·华为交换机
zhendianluli2 小时前
为什么fclose处理的是file而不是fd
linux·服务器·网络
牙牙7052 小时前
部署SFTP服务
linux·服务器·网络
绾樘2 小时前
HCIP—OSPF综合实验
网络·智能路由器
TG:@yunlaoda360 云老大2 小时前
华为云国际站代理商的CloudPond跨境主要有什么用呢?
服务器·网络·华为云
bing_feilong2 小时前
ubuntu网络命令详解
linux·运维·网络
Boop_wu2 小时前
[Java EE] 网络原理(3) https
网络·https·java-ee