我的本意可以用文稿中的一张图来表示,还记得 TCP/IP 层次模型么?我想通过这么一个问题,来展示 TCP/IP 分层的思想。
让我们先看发送端,当应用程序将数据送到发送缓冲区时,调用的是 send 或 write 方法,如果缓存中没有空间,系统调用就会失败或者阻塞。我们说,这个动作事实上是一次”显式拷贝“。而在这之后,数据将会按照 TCP/IP 的分层再次进行拷贝,这层的拷贝对我们来说就不是显式的了。
接下来轮到 TCP 协议栈工作,创建 Packet 报文,并把报文发送到传输队列中(qdisc),传输队列是一个典型的 FIFO 队列,队列的最大值可以通过 ifocnfig 命令输出的 txqueuelen 来查看。通常情况下,这个值有几千报文大小。
TX ring 在网络驱动和网卡之间,也是一个传输请求的队列。
网卡作为物理设备工作在物理层,主要工作是把要发送的报文保存到内部的缓存中,并发送出去。
接下来再看接收端,报文首先到达网卡,由网卡保存在自己的接收缓存中,接下来报文被发送至网络驱动和网卡之间的 RX ring,网络驱动从 RX ring 获取报文 ,然后把报文发送到上层。
这里值得注意的是,网络驱动和上层之间没有缓存,因为网络驱动使用 Napi 进行数据传输。因此,可以认为上层直接从 RX ring 中读取报文。
最后,报文的数据保存在套接字接收缓存中,应用程序从套接字接收缓存中读取数据。
上面的任何一个环节稍有积压,都会对程序性能产生影响。但好消息是,内核和网络设备供应商已经帮我们把一切都打点好了,我们看到和用到的,其实只是冰山上的一角而已。
网友评论