一、协议栈的内部结构

和浏览器不同,协议栈的工作从表面上是看不到的,可能比较难想象,这里我们对整个流程做一个解剖

  • 上面的部分会向下面的部分委派工作
  • 下面的部分接收委派的工作并执行执行
  • 这上下关系知识一个总体的规则,其中也有一部分上下关系不明确或关系相反的情况

image.png

协议栈的上半部分有两块,分别是负责用 TCP 协议收发数据的部分和负责用 UDP 协议收发数据的部分

  • 浏览器、邮件等一般应用程序收发数据时用 TCP
  • DNS 查询等收发较短的控制数据时用 UDP

协议栈的下半部分是用 IP 协议控制网络包收发操作的部分
在互联网上传送数据时,数据会被切分成一个一个的网络包,而将网络包发送给通信对象的操作就是由 IP 负责的
此外,IP 中还包括 ICMP 协议和 ARP 协议

  • ICMP 用于告知嗨咯包传送过程中产生的错误以及各种控制信息
  • ARP 用于根据 IP 地址查询响应的以太网 MAC 地址

二、套接字的实体就是通信控制信息

在协议栈内部有一块用于存放控制信息的内存空间,这里记录了用于控制通信操作的控制信息,例如

  • 通信对象的 IP 地址、端口号、通信操作的进行状态等

套接字只是一个概念,并不存在实体,如果一定要赋予它一个实体,可以说这些控制信息就是套接字的实体

协议栈在执行操作时需要参阅这些控制信息,例如

  • 在发送数据时,需要看一看套接字中的通信对象 IP 地址和端口号,以便向指定的 IP 地址和端口发送数据

套接字中记录了用于控制通信操作的各种控制信息,协议栈则需要根据这些信息判断下一步的行动,这就是套接字的作用

协议栈是根据套接字中记录的控制信息来工作的

在 Windows 中可以用 netstat 命令显示套接字内容

  1. netstat -ano
  • a 不仅显示正在通信的套接字,还显示包括尚未开始通信等状态的所有套接字
  • n 显示 IP 地址和端口号
  • o 显示使用该套接字的程序 PID

展示的内容从左至右依次是

  1. Protocol
    • 使用 TCP/IP 协议通信的情况下,会显示 TCP 或 UDP
  2. Local Address
    • 本地端的 IP 地址和端口号
      • 0.0.0.0 表示不绑定 IP 地址
  3. Foreign Address
    • 远程端的 IP 地址和端口号
      • 0.0.0.0 表示还没有开始通信,没有绑定 IP 地址和端口号
      • 此外,UDP 协议中的套接字不绑定对方的端口号,因此显示 :
  4. State
    • 表示通信状态
      • LISTENING 等待对方连接的状态
      • ESTABLISHED 完成连接并正在进行数据通信的状态
  5. PID
    • 使用该套接字的程序 PID(进程标识符)
      • 可以使用任务管理器来查询 PID 对应的程序名称

三、调用 socket 时的操作

看一看当浏览器调用 socket、connect 等 Socket 库中的程序组件时,协议栈内部是如何工作的
下图是浏览器通过 Socket 库向协议栈发出委托的一系列操作
image.png
在上面这个过程中,协议栈首先会分配用于存放一个套接字所需的内存空间,这个空间需要往里面存入控制信息。套接字刚刚创建时,数据收发操作还没有开始,因此需要在套接字的内存空间中写入表示这一初始状态的控制信息。到这里,创建套接字的操作就完成了。

创建套接字时,首先分配一个套接字所需的内存空间,然后向其中写入初始状态。

接下来,需要将表示这个套接字的描述符告知应用程序。收到描述符之后,应用程序在向协议栈进行收发数据委托时就需要提供这个描述符。

「@浪里淘沙的小法师」