考虑下面的场景,server向client发送数据"_META_DATA_\r\n_USER_DATA_",要求"\r\n"之前的数据_META_DATA_在第一次recv中接收,剩下的recv调用读取_USER_DATA_部分的数据。因为tcp是stream协议,并且_META_DATA_数据不是定长的,所以没有办法保证一次recv调用不读到_USER_DATA_部分的数据,除非一次读取一个字符。这种场景下,recv的MSG_PEEK参数就发挥作用。

recv的原型是ssize_t recv(int s, void *buf, size_t len, int flags); 通常flags都设置为0,此时recv函数读取tcp buffer中的数据到buf中,并从tcp buffer中移除已读取的数据。把flags设置为MSG_PEEK,仅把tcp buffer中的数据读取到buf中,并不把已读取的数据从tcp buffer中移除,再次调用recv仍然可以读到刚才读到的数据。

针对上面的场景,recv(fd, buf, nbuf, MSG_PEEK) 查看数据,查看"\r\n"的位置pos,再recv(fd, buf, pos+2, 0) 读取(并移除)数据。

上述场景描述的比较极端,毕竟很多时候,就算在一次recv中读到了_USER_DATA_部分的数据,仍可以先把这部分数据保存起来,添加到后续的recv数据之前,但是如果不同的recv跨越很多函数,保存数据带来了额外的复杂度。还可以考虑另外的场景,同一个端口支持文本协议和二进制协议,利用MSG_PEEK看一下头几个字符,先判断是文本协议还是二进制协议,再做请求分发,也是不错的选择。当然,真正的recv之前调用使用MSG_PEEK导致额外的一次函数调用。

recv函数的MSG_PEEK标志介绍的更多相关文章

  1. UNIX网络编程——send与recv函数详解

    #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags); ssize_ ...

  2. socket函数send和recv函数

    转自:http://www.cppblog.com/aaxron/archive/2012/04/27/172891.html 在发送端,一次发送4092个字节,在接收端,一次接收4092个字节,但是 ...

  3. Linux下tcp协议socket的recv函数返回时机分析(粘包)

    http://www.vckbase.com/index.php/wv/10http://blog.csdn.net/zlzlei/article/details/7689409 文章一: 当前在网络 ...

  4. socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  5. send()和recv()函数详解

    send()函数 int send( SOCKET s, const char FAR *buf, int len, int flags ); 不论是客户还是服务器应用程序都用send函数来向TCP连 ...

  6. linux内核中send与recv函数详解

    Linux send与recv函数详解 1.简介 #include <sys/socket.h> ssize_t recv(int sockfd, void *buff, size_t n ...

  7. linux Socket send与recv函数详解

    转自:http://www.cnblogs.com/blankqdb/archive/2012/08/30/2663859.html linux send与recv函数详解   1 #include ...

  8. [转]socket使用TCP协议时,send、recv函数解析以及TCP连接关闭的问题

    Tcp协议本身是可靠的,并不等于应用程序用tcp发送数据就一定是可靠的.不管是否阻塞,send发送的大小,并不代表对端recv到多少的数据. 在阻塞模式下, send函数的过程是将应用程序请求发送的数 ...

  9. linux recv函数返回值分析

    函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags); 该函数第一个参数制定接收端套接字描述符; 第二个参数指明一个缓冲区, ...

随机推荐

  1. Python3简单入门

    在Mac和Linux上运行Python时,请打开终端,然后运行python3 Mac OSX 正确地同时安装Python 2.7 和Python3:  http://www.jianshu.com/p ...

  2. 洛谷P4135 作诗 (分块)

    洛谷P4135 作诗 题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章 ...

  3. 浏览器发送URL的编码特性

    转载自:http://blog.csdn.net/wangjun_1218/article/details/4330244 浏览器发送URL的编码特性 尽管有很多规范URL的标准,例如RFC 3987 ...

  4. css渐变知识知多少

    <!DOCTYPE html><html><head><meta charset="utf-8"> <title>教程( ...

  5. Eclipse srever起来时,时间超过45s。

    双击servere的名字,在属性界面上进行修改. 如下图: 修改TimeOut中的值即可.

  6. JavaScript字符串、数组操作总结一

    1.将数组转换成字符串 例子: var  arr=[1,2,3,4,5,6]; var  str=arr.join('|'); str输出为 “1|2|3|4|5|6” 2.数组indexOf()方法 ...

  7. [洛谷P3401] 洛谷树

    洛谷题目连接:洛谷树 题目背景 萌哒的Created equal小仓鼠种了一棵洛谷树! (题目背景是辣鸡小仓鼠乱写的QAQ). 题目描述 树是一个无环.联通的无向图,由n个点和n-1条边构成.树上两个 ...

  8. Java面试知识总结三

    1.SpringMVC在项目中的应用? 1)service层,项目的业务逻辑层,一般先定义一个接口,在写一个实现类,实现所有的接口方法.service的实现类中要加注解@Service(用于标注业务层 ...

  9. JAVA list 列表 字典 dict

    import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; pu ...

  10. mssql手工注入2

    --+ 先说一些函数的说明: substring(str,start,len) 截取字符串的作用,第一个参数为要截取的字符串,第二个参数为从哪里开始截取,第三个参数为截取的长度 ascii(char) ...