协议栈如何处理数据发送请求
副标题:阅读《网络是怎么连接的(户根勤)》读书笔记3
Tips:
- IEEE802.3/802.2因长度太长、效率降低并未完全普及,更古老的以太网DIX规格仍在使用
- TCP/IP协议以前是合为一体的,现在分开成两个
- 像浏览器、邮件等一般的应用程序都是使用TCP收发数据的,而像 DNS 查询等收发较短的控制数据的时候则使用UDP
- ICMP用于告知网络包传送过程中产生的错误以及各种控制消息,ARP 用于根据IP地址查询相应的以太网MAC地址
- 套接字的实体就是通信控制信息:IP地址、端口号、通信操作的进行状态、是否收到响应、执行发送操作后经过了多长时间等
- 图2.3的步骤1中,协议栈申请内存空间准备存放套接字(控制信息),刚刚创建时,数据收发操作还未开始,故写入初始状态的控制信息;之后将套接字描述符告知应用程序
- 步骤2的连接是指双方交换控制信息,必要的信息放在了网络包的头部,另一类放在套接字内存区
- 将浏览器查到的对方IP和端口号等告知协议栈
- 服务器创建套接字(其实一般在服务器启动时已经创建好了),客户端将本机IP和端口号等告知服务器
- 创建一块缓存区,用于临时存放收发的数据
- connect详见后面段落
- 步骤3为数据收发阶段,步骤2结束时,控制流程被交还给应用程序,应用程序调用write将数据以一大串二进制字节序列的形式交给协议栈,协议栈将数据存入发送缓存区中(不选择一次性发送是因为应用程序可能逐行或其他形式发送数据,或者积攒一定量的数据再发送以避免小包)
- 积累多少数据才能发送,要看操作系统的种类和版本,主要看以下参数:
- MTU参数(即一个网络包的最大长度,以太网中一般为1500字节)
- 等待时间(避免积攒太久)
- 步骤3补:TCP模块会设计
序号
和ACK号
,可以计算发送的某包是从第几个字节开始,长度多少了,可以用来确认遗漏情况 - 步骤3补补:客户端在连接时需要计算出与从客户端到服务器方向通信相关的
序号初始值
,发送给服务器,写在SYN值中,不是从1开始,可避免网络攻击;服务器返回ACK号表示确认,并返回反方向的序号初始值
,客户端接收完毕,发送ACK给服务器,服务器接收表示两个序号初始值
传递完毕。注:此步操作再connect中完成 - 步骤4,read程序接收响应,数据进入数据缓存区,在发送请求后接收响应前,read的工作会被挂起,等响应到达时再处理
- 步骤5,调用Socket库的close程序,将TCP头部的FIN比特设为1,套接字记录断开的控制信息,同时通过IP模块向对方发送数据,对方接收到数据后,返回FIN为1和ACK的包,并更改自己的套接字为断开操作状态。此数据被协议栈调取,协议栈告知应用程序数据已经全部收到,通信结束。
- 步骤5补,为了避免误操作,套接字会延迟删除,大约是几分钟
重要!connect过程
- 协议栈中的TCP 模块处创建表示连接控制信息的
头部
,通过 TCP 头部中的发送方和接收方端口号可以找到要连接的套接字 - TCP模块会将信息传递给IP模块并委托它发送
- 网络包由IP模块经网络发送到服务器的IP模块再传递给TCP模块
- 服务器的TCP模块会根据TCP头部信息找到端口号对应的套接字,服务器的套接字会改变状态为
正在连接
- 发回响应:在TCP头部设置双方的端口号、设
SYN比特
(接收连接设为1,若不接受,则不设SYN,改设RST为1),设ACK比特
为1(客户端向服务器发送第一个网络包时,ACK设为0,ACK比特并非前文ACK号,是一个ACK号字段的两个部分),将TCP头部传递给IP模块,委托IP模块向客户端发回响应 - 到达客户端的网络包通过IP模块到达TCP模块,并通过TCP头部的信息确认连接是否成功
- SYN为1表示连接成功,之后向套接字写入服务器的IP、端口,并将状态改为
连接完毕
- ACK为1的响应信息已经到达客户端,相应的,客户端需要将ACK设置为1并发回服务器,告知服务器刚刚的响应包已收到,等服务器收到此包则意味着整个连接操作全部完成
- 此connect也有人称为’session‘,此处不作延伸
ACK号的管理
- 根据网络包平均往返时间调整 ACK 号等待时间,TCP采用了动态调整等待时间的方法,ACK号返回变慢,就延长ACK号等待时间
- 使用滑动窗口管理:在发送一个包之后,不等待 ACK 号返回,而是直接发送后续的一系列包。但是可能出现发送包的频率超过接收方处理能力的情况,严重的后果是造成缓存区溢出。避免的方法是,接收方先告诉发送方自己的承载能力,然后发送方根据这个值对数据发送操作进行控制,注:其中有个名词
窗口字段
,能够接收的最大数据量的大小称为窗口大小
,一般与接收方的缓存区大小一致 - 每接收到一个包,就要向发送方传递ACK号和窗口更新这两个独立的包,会造成效率下降。解决办法:独立包发送前等待一下,凑足两个后一齐发送,可以减少包的数量
已完成全书219页