目录:
TCP首部
最大报文段长度
半关闭
状态转移图
呼入连接请求队列
1.TCP 首部
TCP提供一种面向连接的、可靠的字节流服务。
面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。
TCP通过下列方式来提供可靠性:
TCP对字节流的内容不作任何解释。TCP不知道传输的数据字节流是二进制数据,还是ASCII字符或者其他类型数据。对字节流的解释由TCP连接双方的用层解释 。
IP 数据报格式
- URG 紧急指针(u rgent pointer)有效。
- ACK 确认序号有效。
- PSH 通知接收方应尽快将所收到的数据全部提交给接收进程。
- RST 重新建立连接。
- SYN 同步序号,用来发起一个连接。
- FIN 完成发送任务,终止一个连接。
建立 TCP 连接的”三次握手“
1)请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN)。这个SYN段为报文段1。
2)服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。
3)客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)。
这三个报文段完成连接的建立。这个过程也称为三次握手(three-way handshake)。
当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。
断开TCP连接的“四次握手”
1)主动关闭方(客户端)向服务端发送一个结束符FIN。和SYN一样,一个FIN将占用一个序号。
2)当服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。同时TCP服务器还向应用程序(即丢弃服务器)传送一个文件结束符EOF。
3)接着这个服务器程序就关闭它的连接,导致它的TCP端发送一个FIN(报文段6)。
4)客户必须发回一个确认,并将确认序号设置为收到序号加1(报文段7)。
TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向连接。
TCP 断开连接四次握手原因:
1)当一端收到一个 FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。发送FIN通常是应用层进行关闭的结果。
2)一个TCP连接在收到一个FIN后仍能发送数据。而这对利用半关闭的应用来说是可能的。
2.TCP的半关闭
TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。这就是所谓的半关闭。
如果应用程序不调用close而调用shutdown,且第2个参数值为1,则插口的API支持半关闭 。
左方的客户端开始半关闭,当然也可以由另一端开始。初始端发出的FIN,接着是另一端对这个FIN的ACK报文段。因为接收半关闭的一方仍能发送数据。当收到半关闭的一端在完成它的数据传送后,将发送一个FIN关闭这个方向的连接,这将传送一个文件结束符给发起这个半关闭的应用进程。当对第二个FIN进行确认后,这个连接便彻底关闭了。
3.最大报文段长度
最大报文段长度(MSS)表示TCP传往另一端的最大块数据的长度。
当一个连接建立时,连接的双方都要通告各自的MSS。如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报) 。
当TCP发送一个SYN时,或者是因为一个本地应用进程想发起一个连接,或者是因为另一端的主机收到了一个连接请求,它能将MSS值设置为外出接口上的 MTU长度减去固定的IP首部和TCP首部长度。对于一个以太网,MSS值可达1460字节。
如果目的IP地址为“非本地的( nonlocal )”,MSS通常的默认值为536。而区分地址是本地还是非本地是简单的,如果目的IP地址的网络号与子网号都和我们的相同,则是本地的;如果目的IP地址的网络号与我们的完全不同,则是非本地的;如果目的IP地址的网络号与我们的相同而子网号与我们的不同,则可能是本地的,也可能是非本地的。
TCP协议设置MSS的目的:限制TCP数据报的长度,避免因为超过MTU被IP层分片。
4.TCP 状态转移图
TCP 连接建立和终止时的状态:
TIME_WAIT 状态
也叫 2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段,所以这个时间是有限的。
对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留2倍的MSL 时间。停留 2MSL 时间的结果:
1)可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。
2)在2MSL等待期间,这个连接的客户IP地址和端口号、服务器的IP地址和端口号不能再被使用。任何迟到的报文段将被丢弃。因此来自该连接的一个较早的迟到报文段作为新连接的一部分不可能被建立新连接。
同时打开
两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能性极小。每一方必须发送一个SYN,且这些SYN必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口。这又称为同时打开(simultaneous open)。TCP是特意设计为了可以处理同时打开,对于同时打开它仅建立一条连接而不是两条连接。
同时关闭
双方都执行主动关闭也是可能的,TCP协议也允许这样的同时关闭 。
5.呼入连接请求队列
一个并发服务器调用一个新的进程来处理每个客户请求,因此处于被动连接请求的服务器应该始终准备处理下一个呼入的连接请求。但仍有可能出现当服务器在创建一个新的进程时,或操作系统正忙于处理优先级更高的进程时,到达多个连接请求。当服务器正处于忙时,TCP是如何处理这些呼入的连接请求?在伯克利的TCP实现中采用以下规则:
1) 正等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已被TCP接受(即三次握手已经完成),但还没有被应用层所接受。
注意区分:TCP接受一个连接是将其放入这个队列,而应用层接受连接是将其从该队列中移出。
2) 应用层将指明该队列的最大长度,这个值通常称为积压值(backlog)。它的取值范围是0~5之间的整数,包括0和5(大多数的应用程序都将这个值说明为5)。
3) 当一个连接请求(即SYN)到达时,TCP使用一个算法,根据当前连接队列中的连接数来确定是否接收这个连接。
注意:积压值说明的是TCP监听的端点已被TCP接受而等待应用层接受的最大连接数。这个积压值对系统所允许的最大连接数,或者并发服务器所能并发处理的客户数,并无影响。
4) 如果该TCP监听的端点的连接队列中还有空间,TCP将对SYN进行确认并完成连接的建立。
当客户进程的主动打开成功但服务器的应用层还不知道这个新的连接时,它可能会认为服务器进程已经准备好接收数据了(这种情况下,服务器的TCP仅将接收的数据放入缓冲队列)。
5) 如果连接队列中已没有空间,TCP将不理会收到的SYN,也不发回任何报文段(即不发回RST)。
如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,客户的主动打开最终将超时。