TCP/IP源码(59)——TCP中的三个接收队列
2013-11-10 18:59
253 查看
在Linux内核的TCP实现中,TCP有三个接收队列——除去错误队列。这三个队列分别是struck sock中的sk_receive_queue和sk_backlog,以及struct
tcp_sock中的prequeue。这三个队列作用,网上已经有很多文章论述了。这里只简单介绍一下,
1、sk_receive_queue是真正的接收队列,收到的TCP数据包经过检查和处理后,就会保存到这个队列中。
2、sk_backlog是当socket处于用户进程的上下文时(即用户正在对socket进行系统调用,如recv),Linux收到数据包时,在软中断处理过程中,会将数据包保存到sk_backlog中,然后直接返回。
3、而prequeue则是在,该socket没有正在被用户进程使用时,由软中断直接将数据包保存在prequeue中,然后返回。
我们可以从tcp的接收处理函数中,验证上面的结果。下面的代码来自tcp_v4_rcv函数
网上的大部分资料,都只是介绍了这三个队列的用途。但是看到这里,其实我们应该有一个疑问。backlog和prequeue都是保存的未经处理的数据,为什么需要两个不同的队列呢?为了解答这个疑问,我们需要研究一下prequeue和backlog是如何应用的?前面是两个队列的写入操作,下面看看两个队列何时被读取。prequeue的处理函数tcp_prequeue_process,如前文所说,在TCP的读取数据函数tcp_recvmsg中调用。在tcp_recvmsg的入口,会调用lock_sock来设置sk->sk_lock.owned,表示该sock由用户进程占有,然后会对receive_queue和prequeue中的数据包进行处理。正因为sock被用户进程处理时,会访问prequeu,所以软中断只能将数据保存到backlog中,以避免竞争。那么为什么在sock不由用户进程占有时,只能保存到prequeu中,而不能重入backlog呢?
让我们继续跟进,看看何时处理backlog的数据包。Oh,my god,居然是在__release_sock中,这真的有点出乎我的意料。这也就解释了,为什么需要两个队列来保存未处理数据包。对于sock来说,一共有两种状态:1. 用户进程占用该sock;2.
用户进程未占用该sock;而kernel需要在任何情况下,都要能够保证tcp数据包处理的软中断快速返回。而保存未处理数据包的队列,无论如何也要在上述的一个情况下,访问未处理的数据包。那么这不可避免的会有资源竞争。所以为了避免这种情况,当sock被用户进程占用时,让它处理prequeue中的数据包,软中断则往backlog中保存。当sock不被用户进程占用时,会去访问backlog中的数据包,软中断则往prequeue中保存。
http://blog.chinaunix.net/uid-20671208-id-3595604.html
tcp_sock中的prequeue。这三个队列作用,网上已经有很多文章论述了。这里只简单介绍一下,
1、sk_receive_queue是真正的接收队列,收到的TCP数据包经过检查和处理后,就会保存到这个队列中。
2、sk_backlog是当socket处于用户进程的上下文时(即用户正在对socket进行系统调用,如recv),Linux收到数据包时,在软中断处理过程中,会将数据包保存到sk_backlog中,然后直接返回。
3、而prequeue则是在,该socket没有正在被用户进程使用时,由软中断直接将数据包保存在prequeue中,然后返回。
我们可以从tcp的接收处理函数中,验证上面的结果。下面的代码来自tcp_v4_rcv函数
让我们继续跟进,看看何时处理backlog的数据包。Oh,my god,居然是在__release_sock中,这真的有点出乎我的意料。这也就解释了,为什么需要两个队列来保存未处理数据包。对于sock来说,一共有两种状态:1. 用户进程占用该sock;2.
用户进程未占用该sock;而kernel需要在任何情况下,都要能够保证tcp数据包处理的软中断快速返回。而保存未处理数据包的队列,无论如何也要在上述的一个情况下,访问未处理的数据包。那么这不可避免的会有资源竞争。所以为了避免这种情况,当sock被用户进程占用时,让它处理prequeue中的数据包,软中断则往backlog中保存。当sock不被用户进程占用时,会去访问backlog中的数据包,软中断则往prequeue中保存。
http://blog.chinaunix.net/uid-20671208-id-3595604.html
相关文章推荐
- HttpWebRequest中UserAgent的使用
- 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)
- muduo网络库学习之EventLoop(七):TcpClient、Connector
- socket函数
- 企业小型网络的配置
- UNIX 网络编程环境配置
- 51单片机串口通信,网络上摘取的代码片段
- Weblogic 12c 的 Apache HTTP Server 整合插件(Plug-In)下载地址
- 通过计算主机数来划分子网。
- http://lxr.linux.no/网站首页的部分翻译
- 有道词典“网络已断开”的解决办法
- java网络编程方向
- 深入理解Hadoop集群和网络
- 异步加载网络图片
- 浏览器访问IIS服务器上面的plist文件报错:HTTP Error 404.3 - Not Found
- muduo网络库学习之EventLoop(六):TcpConnection::send()、shutdown()、handleRead()、handleWrite()
- 网络编程 -- gethostbyname() 函数解析
- [转载]网络趣解
- android 判断网络连接是否可用
- 计算机网络_学习笔记 第三章 数据链路层