网络编程基础(UDP 编程)
UDP 报文头部结构如下图所示:
TCP 流式服务和 UDP 数据包服务
TCP 字节流服务中,应用程序对数据的发送和接受是没有边界限制的。UDP 则不然,发送端应用程序每执行一次写操作,UDP 模块就将其封装成一个 UDP 数据报并发送之。接收端必须及时针对每一个 UDP 数据报执行读操作(通过 recvfrom 系统调用),否则就会丢包(这经常发生在较慢的服务器上)。并且,如果用户没有指定足够的应用程序缓冲区来读取 UDP 数据,则 UDP 数据将被截断。
UDP 编程流程:
服务器:socket bind recvfrom/sendto close
客户端:socket recvfrom/sendto close
int recvfrom(int sockfd, void *buff, int len, int flag, struct sockaddr *src_addr, int *addr_len); //接受一个数据报并保存源地址
sockfd:标识一个已连接套接口的描述符
buff:接收数据缓冲区
len:缓冲区的长度
flags:调用操作方式
MSG_PEEK:查看当前数据,数据将被复制到缓冲区中,但并不从输入队列中删除
MSG_OOB:处理外带数据
src_addr:(可选)指针,指向装有原地址的缓冲区
addr_len:(可选)指针,指向 src_addr 缓冲区长度值
返回值:若无错误发生,recvfrom() 返回读入的字节数。如果连接已中止,返回 0。否则的话,返回 SOCKET_ERROR 错误,应用程序通过 WSAGetLastError() 获取相应错误代码。
int sendto(int sockfd, void *buff, int len, int flag, struct sockaddr *src_addr, int addr_len); //向指定目的地发送数据
sockfd:一个标识套接口的描述符
buff:包含待发送数据的缓冲区
len :buff 缓冲区中的数据的长度
flags:调用方式标志位
MSG_DONTROUTE
MSG_OOB:发送外带数据(仅适用于 SO_STREAM)
src_addr:(可选)指针,指向目的套接口的地址
addr_len:src_addr 所指向地址的长度
返回值:若无错误发生,send() 返回所发送数据的总数。否则的话,返回 SOCKET_ERROR 错误,应用程序可通过 WSAGetLastError() 获取响应错误代码。