鸡啄米

首页|IT互联网|数码生活|软件开发|娱乐休闲|职场人生|编程课堂|Android开发网

TCP/UDP网络编程入门教程之二十四:UDP原理——预读MSG_PEEK

       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。其异常信息大概是读取的数据长度小于数据包的长度——而这个正是我们计划中的事情。

Tags:TCP/IP | 2015/11/30 | 发表评论

相关文章: