TCP数据流
1. 引言
如果按照分组数量计算,约有一半的TCP报文段包含成块数据(如FTP、电子邮件等),另一半则包含交互数据(如telnet和rlogin)。
如果按照字节计算,则成块数据与交互数据的比例约为90%和10%。这是因为成块数据的报文段基本上都是满长度(full-sized)的(通常为512字节的用户数据),而交互数据则小得多,研究表明telent和rlogin分组中通常约90%的用户数据小于10字节。
因此TCP需要能处理交互数据和成块数据,但使用的处理算法有所不同。
2. 交互数据流
2.1 经受时延ACK/数据捎带ACK
一个Rlogin连接上键入一个交互命令时会产生4个报文段:
(1)来自客户的交互按键
(2)来自服务器的按键确认
(3)来自服务器的按键回显
(4)来自客户的按键回显确认
如图:
然而,我们一般可以将报文段(2)和(3)进行合并--按键确认与按键回显一起发送(经受时延的确认)
通常TCP在接收到数据时并不立即发送ACK;相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送(有时称这种现象为数据捎带ACK)
绝大多数实现采用的时延为200ms,也就是说,TCP将以最大200ms的时延等待是否有数据一起发送。
2.2 Nagle算法
一个Rlogin连接上客户一般每次发送一个字节到服务器,这就产生了一些41字节长的分组:20字节的IP首部、20字节的TCP首部和1字节的数据。在局域网上,这些小分组(tinygram)通常不会引起拥塞。
但在广域网上,这些小分组则会增加拥塞出现的可能,一种简单和好的方法就是采用Nagle算法。
Nagle算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些少量的分组,并在确认到来时以一个分组的方式发出去。
有时需要关闭Nagle算法:小消息(鼠标移动)必须无时延地发送,以便为进行某种操作的交互用户提供实时的反馈。Socket API用户可以使用TCP_NODELAY选项来关闭Nagle算法。
3. 成块数据流
3.1 滑动窗口
如图
将字节1~11进行标号,接收方通告的窗口称为提出的窗口(offered window),它覆盖了从第4字节到第9字节的区域,表明接收法已经确认了包括第3字节在内的数据,且通告窗口大小为6。
窗口大小与确认序号相对应的,发送方计算它的可用窗口,该窗口表明多少数据可以立即被发送。
当接收方确认数据后,这个滑动窗口向右移动。窗口边沿的相对运动增加或减少了窗口的大小。有如下4种移动情况:
(1)称窗口左边沿向右边沿靠近为窗口合拢,这种现象发生在数据被发送和确认时
(2)当窗口右边沿向右移动时将允许发送更多的数据,称之为窗口张开。这种现象发生在一段的接收进程读取已经确认的数据并释放了TCP的接收缓存时
(3)当右边沿向左移动时,称之为窗口收缩。(不允许)
(4)窗口左边沿向左移动。(不存在)
特别说明:
(1)发送方不必发送一个全窗口大小的数据。
(2)来自接收方的一个报文段确认数据并把窗口向右边滑动。这是因为窗口的大小是相对于确认序号的。
(3)窗口大小可以减小,但是窗口的右边沿却不能够向左移动,如果左边沿到达右边沿,则称为一个零窗口,此时发送方不能够发送任何数据。
(4)接收方在发送一个ACK前不必等待窗口被填满。
3.2 窗口大小
由接收方提供的窗口的大小通常可以由接收进程控制,这将影响TCP的性能。
Socket API允许进程设置发送和接收缓存的大小。接收缓存的大小是该连接上所能够通告的最大窗口大小。有一些应用程序通告修改Socket缓存大小来增加性能。
3.3 PUSH标志
发送方使用该标志通告接收方将所收到的数据全部提交给接收进程。这里的数据包括与PUSH一起发送的数据以及接收方TCP已经为接收进程收到的其他数据。
3.4 慢启动
如果发送方和接收方之间存在多个路由器和速率较慢的链路时,就有可能出现一些问题。一些中间路由器必须缓存分组,并有可能耗尽存储器的空间。
TCP支持一种称为“慢启动(Slow start)”算法。该算法通过观察到新分组进入网络的速率应该与另一端返回确认的速率相同而进行工作。
慢启动为发送方的TCP增加了另一个窗口:拥塞窗口(congestion window),记为cwnd。当与另一网络主机建立TCP连接时,拥塞窗口被初始化为1个报文段(即另一端通告的报文段大小)。
每收到一个ACK,拥塞窗口就增加一个报文段(cwnd以字节为单位,但是慢启动的报文段大小为单位进行增加),发送方取拥塞窗口与通告窗口中的最小值最为发送上限。
拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。
发送方开始时发送一个报文段,然后等待ACK。当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的ACK时,拥塞窗口就增加为4。这是一种指数增加的关系。
当某些点上达到了互联网的容量,于是中间路由器开始丢弃分组。这就通告发送方它的拥塞窗口开的过大。
3.5 紧急方式
TCP提供了“紧急方式”(urgent mode),它使一段可以告诉另一端有些具有某种方式的“紧急数据”已经放置在普通的数据流中。另一端被通告这个紧急数据已被放置在普通数据流中,由接收方决定如何处理。
可以通过TCP首部中的两个字段来发出这种从一端到另一端的紧急数据已经被放置在数据流中的通告。URG比特被置为1,并且一个16位的紧急指针被置为一个正的偏移量,该偏移量必须与TCP首部中的序号字段相加,以便得出紧急数据的最后一个字节的序号。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix