一、协议栈的内部结构
和浏览器不同,协议栈的工作从表面上是看不到的,可能比较难想象,这里我们对整个流程做一个解剖
- 上面的部分会向下面的部分委派工作
- 下面的部分接收委派的工作并执行执行
- 这上下关系知识一个总体的规则,其中也有一部分上下关系不明确或关系相反的情况
协议栈的上半部分有两块,分别是负责用 TCP 协议收发数据的部分和负责用 UDP 协议收发数据的部分
- 浏览器、邮件等一般应用程序收发数据时用 TCP
- DNS 查询等收发较短的控制数据时用 UDP
协议栈的下半部分是用 IP 协议控制网络包收发操作的部分
在互联网上传送数据时,数据会被切分成一个一个的网络包,而将网络包发送给通信对象的操作就是由 IP 负责的
此外,IP 中还包括 ICMP 协议和 ARP 协议
- ICMP 用于告知嗨咯包传送过程中产生的错误以及各种控制信息
- ARP 用于根据 IP 地址查询响应的以太网 MAC 地址
二、套接字的实体就是通信控制信息
在协议栈内部有一块用于存放控制信息的内存空间,这里记录了用于控制通信操作的控制信息,例如
- 通信对象的 IP 地址、端口号、通信操作的进行状态等
套接字只是一个概念,并不存在实体,如果一定要赋予它一个实体,可以说这些控制信息就是套接字的实体
协议栈在执行操作时需要参阅这些控制信息,例如
- 在发送数据时,需要看一看套接字中的通信对象 IP 地址和端口号,以便向指定的 IP 地址和端口发送数据
套接字中记录了用于控制通信操作的各种控制信息,协议栈则需要根据这些信息判断下一步的行动,这就是套接字的作用
协议栈是根据套接字中记录的控制信息来工作的
在 Windows 中可以用 netstat 命令显示套接字内容
netstat -ano
- a 不仅显示正在通信的套接字,还显示包括尚未开始通信等状态的所有套接字
- n 显示 IP 地址和端口号
- o 显示使用该套接字的程序 PID
展示的内容从左至右依次是
- Protocol
- 使用 TCP/IP 协议通信的情况下,会显示 TCP 或 UDP
- Local Address
- 本地端的 IP 地址和端口号
- 0.0.0.0 表示不绑定 IP 地址
- 本地端的 IP 地址和端口号
- Foreign Address
- 远程端的 IP 地址和端口号
- 0.0.0.0 表示还没有开始通信,没有绑定 IP 地址和端口号
- 此外,UDP 协议中的套接字不绑定对方的端口号,因此显示 :
- 远程端的 IP 地址和端口号
- State
- 表示通信状态
- LISTENING 等待对方连接的状态
- ESTABLISHED 完成连接并正在进行数据通信的状态
- 表示通信状态
- PID
- 使用该套接字的程序 PID(进程标识符)
- 可以使用任务管理器来查询 PID 对应的程序名称
- 使用该套接字的程序 PID(进程标识符)
三、调用 socket 时的操作
看一看当浏览器调用 socket、connect 等 Socket 库中的程序组件时,协议栈内部是如何工作的
下图是浏览器通过 Socket 库向协议栈发出委托的一系列操作
在上面这个过程中,协议栈首先会分配用于存放一个套接字所需的内存空间,这个空间需要往里面存入控制信息。套接字刚刚创建时,数据收发操作还没有开始,因此需要在套接字的内存空间中写入表示这一初始状态的控制信息。到这里,创建套接字的操作就完成了。
创建套接字时,首先分配一个套接字所需的内存空间,然后向其中写入初始状态。
接下来,需要将表示这个套接字的描述符告知应用程序。收到描述符之后,应用程序在向协议栈进行收发数据委托时就需要提供这个描述符。
「@浪里淘沙的小法师」