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

}
相关推荐
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
wuyk5552 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
XUEYUAN52122 天前
ASN 自治系统号风控:平台如何通过 IP 所属自治域批量识别代理流量
python·网络协议·http·网络安全·socks5
QYRdata2 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现
CHENKONG_CK2 天前
破解制鞋打磨痛点:RFID赋能去毛刺工序自动化升级
网络·单片机·嵌入式硬件·网络协议·tcp/ip
chshang19922 天前
工业路由器是什么?浅谈5G工业网络中的IR602
网络·物联网·5g·智能路由器
萧瑟余晖2 天前
Netty 核心组件与 Reactor 模型详解
网络·架构
ITxiaobing20232 天前
IP 定位服务选型指南:从准确率到工程落地的技术考察
linux·服务器·网络
wuyk5552 天前
【Socket 进阶之路】第 9 章 Linux 网络服务量产稳定性优化|心跳保活、TIME_WAIT、SO_LINGER、内存池、断线重连、完整异常防护框架
linux·服务器·开发语言·网络·物联网
z落落2 天前
C#UDP+串口服务端+UDP 客户端(含 CRC16 校验)
网络·网络协议·udp