创建套接字
上一篇主要描述了应用程序层的内容,这篇继续往下走,讲一讲协议栈。
协议栈内部结构
客户端的网络结构大致如下图所示:
浏览器、邮件等一般应用程序收发数据时用 TCP 协议;DNS 查询等收发较短的控制数据时用 UDP 协议,因为 UDP 协议不需要交换控制信息。
- IP 协议:用于控制网络包的收发操作。
- ICMP 协议:用于告知网络包传送过程中产生的错误以及各种控制信息
- ARP 协议:根据 IP 地址查询相应的以太网 MAC 地址
套接字 Socket
具体示例
在协议栈内部有一块用于存放控制信息的内存空间,该空间记录了用于控制通信操作的控制信息,例如通信对象的 IP 地址、端口号、通信操作的进行状态等。
Windows 系统环境下可以使用 netstat -ano
命令查看当前电脑上的全部连接信息。
Socket 使用示例
建立连接
连接实际上指的是通信双方交换控制信息,并在套接字中记录这些必要信息、准备数据收发的一连串操作。
如果是 TCP 协议,控制信息将保存在 TCP 头部中,格式如下:
在连接、收发、断开等各个阶段中,每次客户端和服务端之间进行通信时,都需要提供这些控制信息。
TCP/IP 包抽象示例
在 TCP 头部数据填充完成之后,TCP 模块就会将整体传递到 IP 模块并委托它进行发送。
传输数据
影响传输效率的两大因素
由于应用程序传递给协议栈的数据长度是不固定的,协议栈通过配置两个参数来决定什么时候发送数据。
网络包大小:
协议栈会根据 MTU 参数来判断每个网络包能够容纳的数据长度。
- MTU(Maximum Transmission Unit):最大传输单元
- MSS(Maximum Segment Size):最大分段大小
时间:
当应用程序发送数据的频率不高的时候,如果每次都等到长度接近 MSS 时再发送,可能会因为等待时间太长而造成发送延迟。
协议栈的内部有一个计时器,会定时将网络包发送出去。
如果长度优先,那么网络的效率会提高,但可能因为等待填满缓冲区而产生延迟;如果时间优先,延迟时间会变少,但又会降低网络的效率。
连接中的数据交换
- 序号初始值(SEQ NO):用于确认传输过程中不会丢包(根据序号+MSS 长度计算当前已收到多少数据)
- ACK:用于确认网络号已收到
- 滑动窗口:支持并发的收发操作
总结
记住三次握手,四次挥手是不是就 OK 了?