网络编程基础篇学习5--UDP编程

对于TCP连接,当双方的连接建立后,在双方对话时,一定知道对方是谁,这表示这种对话是有上下文的。
而UDP没有这样的上下文,它是一个不可靠的通信协议,没有重传和确认,没有有序控制,也没有拥塞控制。

UDP编程

UDP编程和TCP编程相比很不相同,它的主要过程如下:

UDP编程.png 服务器端创建socket后,绑定到本地端口,调用recvfrom函数等待客户端的报文;
客户端创建socket后,调用sendto函数,向服务器地址和端口发送UDP报文,然后客户端和服务器端进入互相的应答过程。 recvfrom和sendto是UDP用来接收和发送报文的两个主要函数,它们的原型如下:

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void* buff, size_t nbytes, int flags, 
          struct sockaddr* from, socklen_t* addrlen); 

ssize_t sendto(int sockfd, const void* buff, size_t nbytes, int flags,
                const struct sockaddr* to, socklen_t addrlen); 
复制代码

recvfrom函数

sockfd是在本地创建的socket描述符,buff指向本地的缓存,nbytes 表示最大的接收数据字节,flags是和I/O相关的参数。
fromaddrlen两个参数是出参,相当于是函数的返回值,通过这两个参数可以得到对端发送方的地址和端口等信息。这和TCP不一样,TCP是通过accept函数得到的socket描述符信息来决定对端的信息。并且UDP报文每次接收时都会获取对端的信息,这也就是说报文和报文之间是没有上下文的。
recvfrom函数的返回值表示实际接收的字节数。

sendto函数

sendto函数中前四个参数的意义和recvfrom函数一样,而后面两个参数toaddrlen表示发送的对端的地址和端口等信息。sendto函数的返回值表示实际发送的字节数。

如果只运行了客户端会出现什么情况?

如果只运行客户端的话,程序会阻塞在recvfrom上。而在TCP中,如果没有开启服务端,那么TCP客户端的connect函数会直接返回“Connection refused”报错信息。而在 UDP 程序里,则会一直阻塞在这里。
为了防止程序一直阻塞在recvfrom上,可以添加一个超时时间进行处理。

如果服务端进行重启,会出现什么情况?

在UDP中,如果服务端进行了重启,那么之后其依然可以接收到客户端的报文,但在TCP中,服务端重启后,必须重新建立连接才可以发送报文。(UDP报文是“无连接”的)

通过UDP协议发送,sendto函数最大能发送的数据长度是多少?

UDP报文中有16bit的长度字段,所以最大数据长度应该是 65535-20(IP头)-8(UDP头)= 65507字节

猜你喜欢

转载自juejin.im/post/7037021869559513095