recv()和recvfrom()的第4个参数可以调整函数行为。

C++代码
  1. #include <sys/types.h>  
  2. #include <sys/socket.h>  
  3. ssize_t recv(int s, void *buf, size_t len, int flags);  
  4. ssize_t recvfrom(int s, void *buf, size_t len, int flags,  
  5.                               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。其异常信息大概是读取的数据长度小于数据包的长度——而这个正是我们计划中的事情。

除非特别注明,鸡啄米文章均为原创
转载请标明本文地址:http://www.jizhuomi.com/software/471.html
2015年11月30日
作者:鸡啄米 分类:软件开发 浏览: 评论:0