socket 编程入门教程(五)UDP原理:5、预读MSG_PEEK

socket 编程入门教程(五)UDP原理:5、预读MSG_PEEK
recv()和recvfrom()的第4个参数可以调整函数行为。
#include  < sys / types.h >
#include 
< sys / socket.h >
ssize_t recv(
int  s,  void   * buf, size_t len,  int  flags);
ssize_t recvfrom(
int  s,  void   * buf, size_t len,  int  flags,
                              struct  sockaddr  * from, socklen_t  * fromlen);
因为UDP是按数据包接收的,我们在接收之前并不知道这个数据包有多大。一个策略是,我们准备足够大的应用程序缓存以免出错,但是这个“足够大”的概念是建立在我们对传送的数据事先有了解的情况下,比如是我们自己设计服务器端和客户端并且制定应用层协议;另外一种策略是,将一个数据包的相关信息记录在数据包的前面的一些字节中,比如说大小,这样,我们可以通过预读数据包的前面一段,得到这个数据包的相关信息,比如说大小,然后再安排缓存。
这个预读的flag就是MSG_PEEK。使用预读后,RecvQ的下一条UDP数据包信息被读出来,但是并不从RecvQ中弹出。
UDP也可以通过recvfrom()预读获得来向的远程地址,从而可以提供给比如connect()等函数使用。
需要说明的是,在Linux下(我是Debian系统)从一个n字节的UDP数据包中预读取小于n个字节的数据是完全没有问题的;但是在WinSock下会引起一个异常10040(WSAEMSGSIZE),即是说win32下recv()或者recvfrom()在这种情况下会返回-1。其异常信息大概是读取的数据长度小于数据包的长度——而这个正是我们计划中的事情。

你可能感兴趣的:(socket 编程入门教程(五)UDP原理:5、预读MSG_PEEK)