基于UDP的服务器端和客户端

前面我们想过了TCP方式的,现在我们说下UDP套接字的方式,内容较少,但是很实用。
下面通过信件说明UDP的工作原理,这是讲解UDP时使用的传统示例,它与UDP特性完全相符。寄信前应先在信封上填好寄信人和收信人的地址,之后贴上邮票放进邮筒即可。当然,信件的特点使我们无法确认对方是否收到。另外,邮寄过程中也可能发生信件丢失的情况。也就是说,信件是一种不可靠的传输方式。与之类似,UDP提供的同样是不可靠的数据传输服务。
如果只考虑可靠性,TCP的确比UDP好。但UDP在结构上比TCP更简洁。UDP不会发送类似ACK的应答消息,也不会像SEQ那样给数据包分配序号。因此,UDP的性能有时比TCP高出很多。编程中实现UDP也比TCP简单。另外,UDP的可靠性虽比不上TCP,当也不会像想像中那么频繁地发生数据损毁。因此,在更重视性能而非可靠性的情况下,UDP是一种很好的选择。
流控制是区分YDP和TCP的最重要标志。但若从TCP中除去流控制,所剩内容也屈指可数。也就是说,TCP的生命在于流控制。在前面讲过的“与对方套接字连接及断开连接过程”也属于流控制的一部分。

那么,UDP最重要的作用就是将发送机的数据包交付给目标机的UDP套接字,也就是某个端口,某个程序。实现端到端的连接。

2、UDP的高效使用
UDP因为不用在收发数据时进行连接和清除过程以及不用进行流控制,所以速度一般比TCP快,当我们需要一些实时服务时,就需要用到UDP,比如视频聊天;当我们发送压缩文件时,因为如果丢失一点信息就无法解压,所以用TCP方式。

3、实现基于UDP的服务器端/客户端
接下来通过之前介绍的UDP理论实现真正的程序。
3.1UDP中服务器端和客户端没有连接
UDP服务器端/客户端不像TCP那样在连接状态下交换数据,因此与TCP不同,无需经过连接过程。也就是说,不必调用TCP连接过程中调用的listen函数和accept函数。UDP中只有创建套接字的过程和数据交换过程。

3.2UDP服务器端和客户端均只需1个套接字
TCP中,套接字之间应该是一对一的关系。若要向10个客户端提供服务,则除了守门的服务器套接字外,还需要10个服务器端套接字。但在UDP中,不管服务器端还是客户端都只需要1个套接字。之前解释UDP原理时举了信件的例子,收发信件时使用的邮筒可以比喻为UDP套接字。只要附近有1个邮筒,就可以通过它向任意地址寄出信件。同样,只需1个UDP套接字就可以向任意主机传输数据。

3.3、基于UDP的数据I/O函数

创建好TCP套接字后,传输数据时无需再添加地址信息。因为TCP套接字将保持与对方套接字的连接。换言之,TCP套接字知道目标地址信息。但UDP套接字不会保持连接状态(UDP套接字只有简单的邮筒功能),因此每次传输数据都要添加目标地址信息。这相当于寄信前在信件中填写地址。接下来节扫填写地址并传输数据时调用的UDP相关函数。

#include <sys/socket.h>
ssize_t sendto(int sock, void *buf, size_t nbytes, int flags,
              strutc sockaddr *to, socklen_t addrlen);
/*
 * 成功时返回传输的字节数,失败时返回-1
 * sock 用于传输数据的UDP套接字文件描述符
 * buff 保存待传输数据的缓冲地址值
 * nbytes 待传输的数据长度,以字节为单位
 * flags 可选项参数,若没有则传递0
 * to 存有目标地址信息的sockaddr结构体变量的地址值
 * addrlen 传递给参数to的地址值结构体变量长度
 */

上述函数与之前的TCP输出函数最大的区别在于,此函数需要向它传递目标地址信息。接下来介绍接收UDP数据的函数。UDP数据的发送端并不固定,因此该函数定义为可接收发送端信息的形式,也就是将同时返回UDP数据包中的发送端信息。

#include <sys/socket.h>
ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags,
                struct sockaddr *from, socklen_t *addrlen);
/*
 * 成功时返回接收的字节数,失败时返回-1
 * sock 用于接收数据的UDP套接字文件描述符
 * buff 保存接收数据的缓冲地址值
 * nbytes 可接收的最大字节数,故无法超过参数buff所指的缓冲大小
 * flags 可选项参数,若没有则传入0
 * from 存有发送端地址信息的sockaddr结构体变量的地址值
 * addrlen 保存参数from的结构体变量长度的变量地址值
 */

编写UDP程序是最核心的部分就在于上述两个函数,这也说明二者在UDP数据传输中的地位。

猜你喜欢

转载自blog.csdn.net/weixin_53344209/article/details/114435577
今日推荐