tcp 的三个接收队列

prequeue

在linux内核中,每一个网络数据包,都被切分为一个个的skb,这些skb先被内核接收,然后投递到对应的进程处理,进程把skb拷贝到本tcp连接的sk_receive_queue中,然后应答ack。
以往的内核处理这些skb的时候,是直接通过内核调度的,有数据来了,就进行进程调度,这样虽然实时性高,但是会导致进程阻塞,或者调度消耗大的问题。因此内核搞出来一个新的东西叫做,prequeue,skb先统一由内核接收,
然后通过内核原有的进程调度机制进行调度,当调度到某一个进程的时候,该进程发现prequeue中有skb属于自己,于是把prequeue中的skb拷贝到本进程的sk_receive_queue中,并做ack应答。
这样一来,收发网络数据包,就不会引起进程调度了,虽然ack的时间可能会不那么及时,但是cpu的利用率实际上是提高了。

sk_receive_queue

上面已经有所介绍,struct sock 的成员,进程处理prequeue的时候,把skb拷贝缓存到自己的sk_receive_queue中。

backlog

要理解backlog队列的含义,先理解对于一个listening socket,kernel维护的两个队列

  • 未完成队列,指的是还没有完成tcp三次握手的连接的队列,socket状态是SYN_RCVD
  • 完成队列,包含了哪些已经完成三次握手的连接,socket状态是ESTABLISHED
    backlog参数历史上被定义为上面两个队列的和

backlog队列为上面两个队列的和

参考