您的位置:首页 > 理论基础 > 计算机网络

TCP/IP (三) TCP消息的接收

2015-11-25 21:15 543 查看
上一篇文章提到:
先发送数据包data1,再发送数据包data2,
data1的数据是有可能比data2先达到对端的接收缓冲区,
但是对端调用接收函数时,是不可能先读取到data2再读取到data1,
下面说明为什么会出现这种情形。
 
这里先借用陶大师的一张图,
情景:socket为阻塞模式,调用recv等方法时flag标志位为0,未对SO_RCVLOWAT做设置



1.  应用程序开始收取TCP消息,与程序所在的机器网卡上接收到网络里发来的TCP消息,这是两个独立的流程,所以第一篇文章中提到的通过127.0.0.1发送数据,只经过内核,不经过网卡,也就可以理解了。

 

2.接收TCP消息最终会调用tcp_recvmsg方法,而tcp_recvmsg会首先锁住socket,因此socket是可以被多进程同时使用的。

 

3.内核在处理接收到的TCP报文时使用了4个队列容器,分别为receive、out_of_order、prequeue、backlog队列

receive:receive队列是允许用户进程直接读取的,它是将已经接收到的TCP报文,去除了TCP头部、排好序放入的、用户进程可以直接按序读取的队列

out_of_order:失序的数据包,暂时存放

prequeue:未被处理的数据包,暂时存放

backlog:未被处理的数据包,暂时存放

这里的数据流是比较复杂的,有兴趣研究清楚的可以点击文章末尾推荐的链接进去学习,这里就不搬陶大师的劳动成果了。 

4.flags参数MSG_PEEK标志位会导致receive队列不会删除报文,MSG_PEEK主要用于多进程读取同一套接字的情形

5.阻塞socket模式下,flags参数中若携带MSG_WAITALL标志位,则意味着必须等到读取到len长度的消息才能返回,否则按SO_RCVLOWAT属性处理

参考资料:《tcp/ip详解卷1》

参考文章:http://blog.csdn.net/russell_tao/article/details/9950615 强烈推荐!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tcp linux 网络编程