CPU工作队列

image.png

socket对象的结构

image.png
当进程A执行到创建socket的语句时,操作系统会创建一个由文件 系统管理的socket对象。
这个socket对象包含了

  • 发送缓冲区
  • 接收缓冲区
  • 等待队列等成员

socket的等待队列是个非常重要的结构,它指向所有需要等待该socket事件的进程。

当socket 接收到数据后,操作系统将该socket等待队列上的进程重新放回到工作队列,该进程变成运行状态,继续执行代码。也由于socket 的接收缓冲区经有了数据,recv可以返回接收到的数据。

问题1:内核如何知道接收的网络数据时属于哪个socket ?

socket数据包格式 (源ip,源端口,协议,目的ip, 目的端口)
一般通过 目的ip, 目的端口 就可以识别出来接收到的网络数据属于哪个socket。如果目的ip,目的端口相同呢?
其实多个客户端与同一个服务端建立了连接,这个时候内核就会有多个socket.并且为它们分配多个fd文件描述符。它们收到网络数据后无法通过目的端口来直接匹配socket, 还需要再通过源ip和端来确定属于哪个socket。

问题2:内核如何同时监控多个socket?

内核负责轮询所有socket,当某个socket有数据到达了,就通知用户进程。
目前的经典解决办法: I/O多路复用- IO multiplexing
多路复用在Linux内核代码迭代过程中依次支持了三种调用:

  • SELECT
  • POLL
  • EPOLL