天天看点

三次握手、四次挥手和2MSL

建立连接-三次握手

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。以上称为三次握手。 

<a href="http://s3.51cto.com/wyfs02/M02/71/7D/wKiom1XRq9aBYiBIAAFbSqrASQ4353.jpg" target="_blank"></a>

145.254.160.237向65.208.228.223发送seq,同时SYN标志位设置为1;

65.208.228.223接收到请求报文,回复seq和ack(ack=seq+1),同时SYN和ACK标志位设置为1;

请求端接收到确认报文报,回复ACK进行确认,同时seq=seq+1和ack; 

初始化序列号:与操作系统有关,操作系统开机时通过某个算法将序列号上涨,在某一时刻进行三次握手,握手建立成功之后,初始化系列号增长跟传输字节数有关系。不在通过原来的算法增长。

四次挥手:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭[1] 。

TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。

服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。

服务器关闭客户端的连接,发送一个FIN给客户端。

客户端发回ACK报文确认,并将确认序号设置为收到序号加1。

<a href="http://s3.51cto.com/wyfs02/M00/71/7E/wKiom1XR1MHTdiOnAACUjKTqHCw651.jpg" target="_blank"></a>

TIME_WAIT状态也成为2MSL等待状态。每个TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。

RFC中之处MSL为2分钟,然后现实中常用值是30秒,1分钟或者2分钟。

对于一个具体实现所给定的MSL值,处理原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该链接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防止这个ACK丢失。

这种2MSL等待的另一个结果就是这个TCP连接在2MSL等待时间,这个连接的socket不能再被使用,只能在2MSL结束之后才能再被使用。

在连接处于2MSL等待时,任何迟到的报文段将被丢弃,因为处于2MSL等待的,有该插口对(socket pair)定义的链接在这段时间内不能再被使用。

最大报文长度

当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS只能出现在SYN报文段中)。如果一方不接收来自另一方的MSS值,则MSS就定为默认的536字节。

一般来说,如果没有分段发生,MSS还是越大越好。报文段越大允许每个报文段传送的数据就越多,相对IP和TCP首部有更高的网络利用率。当TCP发送一个SYN时,或者因为一个本地应用进程想发起一个连接,或者是因为另一端的主机收到了一个连接请求,它能将MSS值设置为外出口的MTU长度减去IP首部和TCP首部,对于一个以太网,MSS值可达到1460字节。

TCP 提供面向连接、可靠的字节流服务

面向连接意味着两个使用TCP的应用在彼此交换数据前先建立一个TCP连接

TCP通过下列方式提供可靠性:

1.应用数据被分割成TCP认为最合适发送的数据块(一般情况下,TCP的包不会超过1500,因为TCP会在三次握手时候协商最大传输单元)

2.当TCP发送一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。(发一个包,等待确认,如果不对这个包进行确认,会在一定时间内进行重发)

3.当TCP收到发自TCP连接另一端的数据,它将发送一个确认,这个确认不是立即发送,通常将推迟几分之一秒。(收到包之后,不会立即确认,会等待几分之一秒之后)

4.TCP将保持它首部和数据的校验和(计算校验和时需要加入伪首部进行验证校验和)

5.既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。

6.既然IP数据报发生重复,TCP的接收端必须丢弃重复的数据。()

7.TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。(缓存溢出或者缓存不够,会通知发起方,发起方就不会再继续发送)

每个TCP段都包含源端口和目的端口号,用于寻找发端和接受端应用进程。这两个值加上IP首部中的源IP地址和目的IP地址唯一确定一个TCP连接。

一个IP地址和一个端口号也成为一个插口(socket),插口对(socketpair)(包含客户IP地址、客户端口号、服务器IP地址和服务器端口号的四元组)可唯一确定互联网络中每个TCP连接的双方

序号用来标识从TCP发送端向TCP发送端发送的数据字节流,它标识在这个报文段中的第一个数字字节。如果将字节流看做在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32bit的无符号数,序号到达23^2-1后从0开始。SYN标志消耗了一个序号,算一个字节,同样FIN也算一个字节,其他ACK,RST均不算。

确认序号应当是上次已经成功收到数据字节序号加1.只有ACK标志为1时确认序号字段才有效。

发送ACK无需任何代价,因为32bit的确认序号字段和ACK标志一样,总是TCP首部的一部分。因此,我们看到一旦一个连接建立起来,这个字段总是被设置,ACK标志也总是被设置为1.

TCP为应用层提供全双工服务。这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。

TCP首部最多有60字节的首部,没有任何选项字段,正常长度都是20字节。

TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16bit字段,因而窗口大小最大为65535字节。

检验和覆盖整个的TCP报文段:TCP首部和TCP数据。这是一个强制性的字段,一定是由发起段计算和存储,并有接收端进行验证。TCP检验和的计算和UDP的计算相似。

只有当URG标志置为1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

最常见的可选字段是最长报文大小,又称为MSS(Maximum SegmentSize)。每个链接方通常都在通信的第一个报文段(为建立连接而设置SYN标志的那个段)中指明这个选项。它表明本端所能接收最大长度的报文段。

TCP报文段的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超市的许多情况中,也会发送不带任何数据的报文段。

本文转自 安安安安森  51CTO博客,原文链接:http://blog.51cto.com/smallc/1685328,如需转载请自行联系原作者

继续阅读