UDP相比TCP是无连接的。
它收发数据是通过recvfrom和sendto两个函数。
它们的原型如下:
ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);
ssize_t sendto(int sockfd, void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t *addrlen)。
UDP客户端和服务端通信过程引用书中图如下:
相比于TCP,UDP客户端在socket之后就开始发送数据;UDP服务端在bind之后就开始接收数据。
UDP客户端发送数据时,有两点要考虑:
1.发送数据过快。
2.服务器进程未运行。
(1).发送数据过快
由于UDP不必等待来自服务端的应答,因此它可以一直发送数据。这样就很容易将服务端淹没,行别地,如果客户端发送数据的带宽大于服务端的带宽,就更容易出现这样的现象。事实上,服务端在接收到来自客户端的数据时,是暂时先把数据存在一个缓冲区中,然后从其中一个一个地拿数据。如果服务端的缓冲区满了,那么后来的数据报就会被丢弃,这就造成了数据的丢失。UDP发送数据过快可以通过限制客户端的发送数据包的数量,或扩大服务端的缓存容量来解决。
(2).发送的服务端不存在
当UDP发送的服务端不存在时,会有一个端口不可达的错误。但UDP并不会收到这样的错误。如果UDP和服务器端进行了 connect,那么这个错误就会返回给UDP客户端。此外,当UDP客户端进行了connect操作后,它之后发送的数据也就确定了发送的对象(如果一台机器上有多个IP,那么未进行connect的UDP会发到这几个IP中的一个)。
connect的UDP和非connec的UDP通信过程比较(以发送两个数据报为例):
非connect:
1.连接套接字。
2.输出第一个数据报。
3.断开套接字。
4.连接套接字。
5.输出第二个数据报。
6.断开套接字。
connect:
1.连接套接字。
2.输出第一个数据报。
3.输出第二个数据报。
比较可以看出当要多次向一个服务端发送数据时,UDP还是连接要高效些。