TCP/IP传输(三)
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
收发数据
HTTP请求消息传递协议栈
即从应用程序中调用write将发送数据交给协议栈,协议栈执行发送操作:
- 协议栈不处理数据,只是统一当作一定长度的二进制字节序列。
- 协议栈先将数据存放在内部的发送缓冲区,并等待应用程序的下一段数据。(应用程序自行决定交给协议栈的数据量,协议栈并不能控制,因此为了保证效率会先积累至阈值再发送)
- 阈值是由(1)MTU(最大传输单元——一个网络包的最大长度,以太网中一般为 1500 字节。),MSS(最大分段大小——MTU 是包含头部的总长度,MTU 减去头部的长度后得到的长度就是一个网络包中所能容纳的最大数据长度)。
- 阈值是由(2)时间,协议栈内有一个计时器,每经过一定时间,就会把网络包发送出去。以上两个判断要素决定的。
- 图解
拆分数据
当请求消息是提交表单消息时,长度会超过一个网络包的大小,
- 这时存储在缓冲区的数据需要以MSS长度为单位拆分。
- 当判断需要发送这些数据时,在每一块数据前面加上 TCP 头部, 并根据套接字中记录的控制信息标记发送方和接收方的端口号,然后交给 IP 模块来执行发送数据的操作。
- 图解:
确认网络包收到
通过返回ACK号(两部分,一设置在TCP头部的ACK号中写入数据长度,二是将控制位的ACK比特设为1)
- 为了防御攻击,将序号的初始值随机(序号初始值会在SYN设为1的同时设置序号字段的值告诉通信对方)。
- 在TCP双向收发时,客户端和服务器双方都需要计算各自序号,双方需要在连接过程中互相告知自己计算的序号初始值。
- TCP 采用该方式确认对方是否收到了数据,在得到确认之前,发送过的包都会保存在发送缓冲区中。如果对方没有返回某些包对应的 ACK 号,那么就重新发送这些包。
- 通过这一机制,可以确认接收方有没有收到某个包,如果没有收到则重新发送,这样无论网络中发生任何错误,都可以发现并采取补救措施(重传网络包)。而且避免了在其他结构进行补救。
- 通过“序号”和“ACK 号”可以确认接收方是否收到了网络包。
调整ACK号等待时间
即网络的错误检测和补偿机制
- 返回超时时间——ACK号的等待时间
TCP动态调整等待时间——由ACK号返回所需时间来判断。(TCP 会在发送数据的过程中持续测量 ACK 号的返回时间,如果 ACK 号返回变慢,则相应延长等待时间;相对地,如果 ACK 号 马上就能返回,则相应缩短等待时间)。
滑动窗口
即发送一个包之后,不等待 ACK 号返回,而是直接发送后续的一系列包。(等待 ACK 号的这段时间就被有效利用)。
为了避免出现缓冲区由于包过多而溢出的现象:
接收方需要告诉发送方自己最多能接收多少数据——(叫做窗口大小),然后发送方根据这个值对数据发送操作进行控制。
下面是从右往左发送数据的图解:
注:发送也是双向的
ACK与窗口合并
为了提高收发数据效率,需要考虑返回 ACK 号和更新窗口的时机。
- 更新窗口大小的时机是接收方从缓冲区中取出数据传递给应用程序时。
- 收到数据之后马上就进行向发送方返回 ACK 号。
中和两个方向:
接收方在发送 ACK 号和窗口更新时会等待一段时间(这个过程中很有可能会出现其他的通知操作)把两种通知合并在一个包里面发送。
接收HTTP响应消息
- 调用read程序获取响应消息。
- 控制流程转移到协议栈
- 协议栈将应用程序的委托(从接收缓冲区中取出数据并传递给应用程序)暂时挂起 ,待服务器返回的响应消息到达再继续执行接收操作。
第三步的具体操作: - 协议栈判断收到的数据块和 TCP 头部的内容是否有数据丢失,正常则返回 ACK 号。
- 协议栈将数据块暂存到接收缓冲区中,将数据块按顺序连接起来还原出原始的数据.
- 将数据交给应用程序。

浙公网安备 33010602011771号