面向连接的运输:TCP
TCP连接
TCP被称为面向连接的,因为在应用程序开始互传数据之前,TCP会先建立一个连接,该连接的建立涉及到三次“握手”。
TCP的连接不是一条真实存在的电路,而是一条逻辑链接,其共同状态仅保留在两个通信端系统的TCP程序中。
TCP连接也是点对点的,即TCP连接只能存在于一对一对的主机之间,不允许多于两台主机的共同建立一条TCP连接,最大主机数量为两台。
三次握手的简述
1.客户首先发送一个特殊的TCP报文段。
2.服务器用另一个特殊的TCP报文段来响应。
3.最后,客户用第三个特殊报文段作为响应。
前两个报文段不承载“有效载荷”,即不包含应用层数据。而第三个报文段可以承载有效载荷。
这个过程被称为三次握手。
TCP连接的组成
客户进程通过套接字传递数据流,数据一旦通过该门,它就由客户中的TCP控制,TCP将这些数据引导到该连接的发送缓存里。
发送缓存是三次握手期间设置的缓存之一。
随后TCP将不时地从缓存里取出一块数据,并将数据传递给网络层,并且发送给接收方。
TCP从缓存中取出并放入报文段的数据数量受限于最大报文段长度(MSS)。
MSS通常由本地发送主机发送的最大链路层帧长度(即最大传输单元MTU)来设置。
TCP在接收端接收到一个报文段后,会将该报文段存入接收缓存中,应用程序则从接收缓存中取得数据。
TCP连接的组成包括:一台主机上的发送缓存、套接字、变量,另一台主机上的接收缓存、套接字、变量。
TCP报文段结构
TCP报文段主要包含下列字段:
1.32比特的序号字段、32比特的确认号字段。
2.16比特的接收窗口字段,用来流量控制。
3.4比特的首部长度字段,用来标识TCP首部长度。
4.可选与变长的选项字段,用于发送方与接收方协商最大报文长度(MSS)时。
5.6比特的标志字段。
序号和确认号
TCP对序号的使用建立在传送的字节流上吗,并不建立在传送的报文段序列之上,一个报文段的序号是该报文段首字母的序号。
例如下面传送一个500 000字节的文件,其MSS为1000字节,数据流的首字节编号是0.
则下图标识了文件数据被换分成不同TCP报文段的方式:
TCP的累积确认
现在假设主机A收到了主机B的字节0~535的报文段,以及另一个包含字节900~1000的报文段。
但没有收到536~899的报文段。所以主机A为了重新构建主机B的数据流,仍在等待字节536(和其
后的字节)。因此,A到B的下一个报文段将在确认号字段中包含536.
因为TCP只确认该流中第一个字节,所以TCP被称为提供累积确认。
下面是Telnet:序号和确认号的一个典型示意图:
往返时间的估计与超时
因为TCP需要实现超时/重传机制,但是超时的时间该怎么设置呢?重传的时间又该设置为多少呢?
为此需要根据往返时间来测定这个超时的时间,但是往返时间的动态测定显然是不现实的,为此我们可以估计往返时间。
估计往返时间
估计往返时间由如下方法来完成:
1.报文段的样本RTT(SampleRTT)就是从某报文段被发出到该报文段被接收之间的时间量。
大多数TCP的实现仅在某个时刻做一次SampleRTT测量。
然后对于SampleRTT的值也许都是非典型的,因此我们引入了一个典型的值,叫做
EstimatedRTT,也就是动态的RTT。
它使用如下公式获得:
EstimatedRTT是一个SampleRTT的加权平均值。
从统计学观点讲,这种平均被称为指数加权移动平均(EWMA)。
下图是一个SampleRTT和EstimatedRTT的例子:
除了估算RTT以外,我们还可以测量RTT的变化,也就是RTT偏差DevRTT:
DevRTT是一个SampleRTT与Estimated之间差值的EWMA,如果SampleRTT值波动较小,那么DevRTT的值就会很小,如果波动很大,那么DevRTT的值就会很大。
设置和管理重传超时间隔
TCP超时间隔应该大于等于EstimatedRTT,否则将会造成不必要的重传,但是也不应该比EstimatedRTT大太多。
TimeoutInterval = EstimatedRTT + 4·DevRTT
可靠数据传输
因为IP是不可靠的,所以TCP在IP之上创建了一种可靠数据传输服务。
在TCP上传输的报文段,通过一个定时器来管理,通过这种管理方法,TCP实现了可靠数据传输。
下面是一个TCP发送方高度简化的模型:
关于以上的模型,TCP必须相应三个主要事件:
1.当上层应用传送数据到TCP时,TCP通过将上层应用数据打包成报文段并且转移到TCP发送缓存中。
2.超时。即TCP通过重传引起超时的报文段来响应超时事件。
3.收到一个来自接收方的确认报文段(ACK包含的一个有效ACK字段值),TCP将这个值y个变量
SendBase进行比较。因为SendBase时最早未被确认的字节的序号,因此SendBase是最后一个已
经被确认的字节的序号,TCP采用累积确认,所以一旦y大于SendBase说明ACK是在确认或多个
报文段。因此需要更新SendBase的值。
流量控制
TCP将发送方的数据传送给接收方缓存,而应用程序中则从该缓存中读取数据,并不是数据一到达
立马读取。但如果程序很久没有读取数据,那么缓存可能会被很多数据所撑爆,造成数据溢出。
因此TCP为它的应用程序提供了流量控制服务。
流量控制是一个速度匹配服务,即发送方和接收方应用程序的读取速率相匹配。
流量控制的实现
TCP通过让发送方维护一个称为接收窗口的变量来提供流量控制。该窗口用于给发送方一个提示,
即接收方还有多少可用的缓存空间。
下面我们定义两个变量:
LastByteRead:主机B上的应用进程从缓存中读出的数据流的最后一个字节的编号。
LastByteRcvd:从网络中达到B接收缓存中的数据流的最后一个字节编号。
因此,我们给出下面式子必须成立:
LastByteRcvd - LastByteRead <= RcvBuffer(接收缓存)
而接收窗口用rwnd标识,根据接收缓存可用空间的数量来设置:
rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]
注意到空间是随着时间变化的,所以rwnd也是动态的。
下图也是一个对于rwnd的一个图示:
而接受主机B则将rwnd放入确认报文段发送给A,从而通知A在该连接的缓存中还有多少可用空间。
特别注意,发送方在接收方的接收窗口也就是rwnd为0时,发送方会继续发送一个只有一个字节数
据的报文段。这些报文段会被接收方确认,最终缓存将开始清空,并且此时返回的确认报文段是一
个非0的rwnd值。
(如果不这样做,在发送方接收到rwnd为0,也就是接收窗口已经满了,因此发送方会被堵塞,但
是因为发送方不发送一个报文段,接收方也不会发送一个确认报文段包含rwnd。所以此时发送方
不知道接收方的rwnd是否已经被清空了,也就是缓存中的数据是否已经被应用程序取走部分,或
者全部取走了。)
TCP连接管理
下面我们来特别仔细地观察一下如何建立和拆除一条TCP连接,涉及到三次握手。
下面我们假设一个客户的进程想要与服务器上的一个进程建立一个连接,则TCP会用以下方式来与
服务器TCP建立连接:
1.客户端的TCP首先向服务器端的的TCP发送一个特殊的TCP报文段。该报文段不包含应用层数
据。但是在报文段的首部中的一个标志位(SYN比特标志位)被置为1。所以这个报文段也被称为
SYN报文段。
同时,客户会随机选择一个初始序号,并将此编号放置于该起始的TCP SYN报文段的序号字段
中,该报文段会被封装在一个IP数据包中发送给服务器。
2.当服务器接收到数据报后,会从中提取出TCP SYN报文段,并且为该TCP连接分配TCP缓存和
变量,并向客户TCP发送允许连接的报文段。这个允许连接的报文段也不包含应用层数据。但在
报文段首部包含三个重要信息。
首先,SYN比特被置为1。
其次,该TCP报文段的首部被指为client_isn + 1。
最后,服务器选择自己的初始序号(server_isn)并且将它放进TCP报文段的序号字段中。
这一个允许连接的报文段通俗点来说就是:
“我收到了你发起连接的SYN分组,该分组带有初始序号client_isn。我同意建立该连接,我的初始
序号为server_isn”,该报文段也被称为SYNACK报文段。
3.在接收到SYNACK报文段后,客户也要给该连接分配缓存和变量,客户机向服务器发送另外一个
报文段,该报文段也是最后一个报文段,对服务器允许连接的报文段进行一次确认。
(通过将server_isn + 1放置到TCP报文段首部的确认字段中来完成此项工作)。
此时连接已经建立了,所以该报文段的SYN比特被置为0。
该报文段可以携带客户到服务器的数据。
一旦完成这三个步骤,客户和服务器就可以相互发送数据报文段了,并且此后的所有报文段的SYN
比特都会是0.
下面是一个TCP三次握手报文段交换的例子图:
而对于TCP连接的中断,客户机的进程和服务器的进程任何一个进程都可以终止该连接,当连接终
止后,主机中的“资源”(变量和缓存)将会被释放。
例如,当客户想要关闭一个TCP连接,那么应用程序对TCP发出一个关闭连接的命令,TCP接收到
命令后,对服务器发送一个特殊的TCP报文段。
该报文段的首部FIN比特标志位被置为1,用于表示需要关闭TCP连接。
而服务器TCP接收到这个报文段后,就向客户发送一个确认关闭的报文段。
在经过一小段时间后,服务器再向客户发送一个关闭报文段,这个关闭报文段的FIN比特标志位也
是1。
最后客户对服务器的关闭报文段进行回应,此时两台主机上的资源就都释放了。
下图是该过程的一个示例图:
下图是一个客户TCP在建立连接->传送数据->关闭连接所有的状态图:
下面来考虑一下,当一台主机接收到一个TCP报文段,该报文段的源IP或端口号并不与主机的套接
字相匹配。
因此,该主机将发送一个特殊重置报文段。该报文段将受不得RST比特标志位置为1.文章来源:https://www.toymoban.com/news/detail-720258.html
告诉源:“我没有那个报文段的套接字,请不要再发送该报文段了。”文章来源地址https://www.toymoban.com/news/detail-720258.html
到了这里,关于计算机网络-TCP协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!