这是我对TCP / IP中传入数据流的理解
内核从网络接口向其缓冲区读取数据
内核将数据从其缓冲区复制到TCP套接字缓冲区,其中Sliding Window工作
被read()阻塞的程序唤醒并从套接字缓冲区复制数据 .
我对滑动窗口的位置有点困惑,或者它与套接字缓冲区相同
Linux不将TCP的滑动窗口作为单独的缓冲区处理,而是将几个索引表示已经接收/读取了多少 . Linux内核数据包处理过程可以通过多种方式进行描述,并且可以分为小部分,因为您需要更深入,但一般流程如下:
内核准备通过网络接口接收数据,它准备SKB(套接字缓冲区)数据结构并将它们映射到接口Rx DMA缓冲环 .
当数据包到达时,它们会填充这些预先配置的缓冲区,并在数据包到达的中断上下文中通知内核 . 在此上下文中,缓冲区被移动到网络堆栈的recv队列,以便从中断上下文中处理它们 .
网络堆栈检索这些数据包并相应地处理它们,最终到达TCP层(如果它们确实是TCP数据包),然后TCP层处理窗口 .
请参阅 struct tcp_sock 成员 u32 rcv_wnd ,然后在 tp->rcvq_space.space 中将其用作窗口中的每个连接空间 .
struct tcp_sock
u32 rcv_wnd
tp->rcvq_space.space
缓冲区被添加到套接字接收队列,并作为流数据在 tcp_recvmsg() 中相应读取
tcp_recvmsg()
这里需要记住的重要一点是,复制是关于性能的最糟糕的事情 . 因此,内核将始终(除非绝对必要)将避免复制并使用指针代替 .
1 回答
Linux不将TCP的滑动窗口作为单独的缓冲区处理,而是将几个索引表示已经接收/读取了多少 . Linux内核数据包处理过程可以通过多种方式进行描述,并且可以分为小部分,因为您需要更深入,但一般流程如下:
内核准备通过网络接口接收数据,它准备SKB(套接字缓冲区)数据结构并将它们映射到接口Rx DMA缓冲环 .
当数据包到达时,它们会填充这些预先配置的缓冲区,并在数据包到达的中断上下文中通知内核 . 在此上下文中,缓冲区被移动到网络堆栈的recv队列,以便从中断上下文中处理它们 .
网络堆栈检索这些数据包并相应地处理它们,最终到达TCP层(如果它们确实是TCP数据包),然后TCP层处理窗口 .
请参阅
struct tcp_sock
成员u32 rcv_wnd
,然后在tp->rcvq_space.space
中将其用作窗口中的每个连接空间 .缓冲区被添加到套接字接收队列,并作为流数据在
tcp_recvmsg()
中相应读取这里需要记住的重要一点是,复制是关于性能的最糟糕的事情 . 因此,内核将始终(除非绝对必要)将避免复制并使用指针代替 .