网络编程——UDP编程
前言
UDP是User Datagram Protocol的缩写,直译为用户数据报协议。
UDP是不可靠传输协议,没有连接和应答机制,导致UDP在发送数据时,根本不清楚通信线路的连通状态,所以UDP传输数据时,无法保证数据一定能发送给对方。
每次传输数据时,必须指定对方的IP和端口。对于UDP来说,UDP协议没有建立连接特性,所以UDP协议没有自动记录对方IP和端口的特点,因此每次发送数据时,应用程序必须亲自指定对方的IP和端口,只有这样才能将数据发送给对方。
UDP使用场景
对于数据量很大但是允许数据丢失的数据来说,可以使用UDP通信。比如像视频、音频等这类数据,尽管数据量很大,但是就算数据有所丢的话,对通信质量不会有太大影响,此时就可以使用UDP来传输。当然,我们在开发项目时,如果有现成的调用UDP的应用层协议,我们可以直接这些应用层协议,这些协议代码是可以到网上下载或者购买的,否者我们就自己亲自调用UDP来实现。比如我们在开发与视频监控相关的网络程序时(主要时客户端),往往会使用RSTP或者RTP应用层协议来传输监控视频数据,RSTP和RTP底层实际上使用的就是UDP协议。
UDP的编程模型

UDP通信双方要做的事情一摸一样的,所以对于UDP通信的双方来说,不需要区分谁是服务器端、谁是客户端,通信双方的身份完全是对等的,所以UDP通信也被称为对等通信,或者叫“点对点”通信。
编写UDP程序流程
第1步:调用socket创建套接字文件
int socket(int domain, int type, int protocol);
第2步:bind绑定固定的ip和端口
如果只是使用UDP发送数据,可以不绑定固定的ip和端口,如果要接收数据的话,必须绑定固定的ip和端口。
疑问:为什么UDP接收数据时需要bind 固定的ip和端口?
如果不绑定,每次使用的都是自动设置的ip和端口,自动设置的话,ip和端口就是不定的,如果每次都是变化的,发送数据端在指定IP和端口时就不知所应该写什么了。所以如果要接收数据,就必须绑定固定的IP和端口。
第3步:调用sendto和recvfrom函数,发送和接收数据
疑问:为什么没有listen和accept?
UDP没有连接的过程,listen和accept是TCP连接时才会用到函数,既然UDP没有连接,自然也就用不到了。
sendto
原型
#include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
功能
发送数据,当后两个参数为NULL和0时,功能等价于send,send专门用于TCP这种面向连接的通信,但对于像UDP这种非连接的通信,必须使用sendto,因为此时必须使用最后两个参数。
参数
sockfd:socket返回的套接字描述符,对于UDP来说,套接字描述符直接用于通信。
buf:存放数据的应用缓存
len:应用缓存的大小。
flags:一般写0,表示阻塞发送数据。其它常用的选项与send的flags一样。
dest_addr:填写目标ip和端口
对于UDP来说,UDP没有连接的过程,所以没有自动记录对方的ip和端口,所以每次发送数据的时候,都需要指定对方的ip和端口。
addelen:dest_addr的大小
返回值
成功返回发送的字节数,失败返回-1,errno被设置
recvfrom
原型
#include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
功能
接收数据,最后两个参数与NULL和NULL时,功能与recv功能相同。UDP通信时,常使用的是recvfrom函数,因为需要用到后两个参数。
参数
sockfd:socket返回的套接字文件描述符
buf:应用缓存,用于存放接收到的数据
len:buf的大小
flags:一般写0,表示阻塞接收数据。其它的常用设置同recv函数
src_addr:用于保存“数据发送方”的ip和端口,以便“接收方”回答对方。
如果是局域网通信,ip就是局域网ip,如果是广域网通信,ip就是对方的所在路由器的公网ip。
如果不需要回答对方数据的话,可以不用保存对方的ip和端口,这时recvfrom的最后两个参数写NULL,此时与recv函数的功能完全等价。
addrlen:src_addr的大小
返回值
成功返回接收到的字节数,失败返回-1,ernno被设置
UDP因为没有“连接和应答”这种确认机制,所以UDP是不可靠通信,不过我们自己可以在应用层加入确认机制,以弥补UDP的补足。比如每次使用UDP通信发送数据给对方后,对方必须回答,如果对方没有回答或者回答数据有错,发送方就重发,以此保证UDP的通信的可靠性,这就是通过应用程序来弥补UDP的不可靠性。

浙公网安备 33010602011771号