TCP三次握手和四次挥手

来源:互联网 发布:python缺省参数 编辑:程序博客网 时间:2024/06/05 23:45


16位源端口号:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是标识报文的返回地址。

16位目的端口号:16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。我们知道端口号就是标识特定主机上的唯一进程的,而IP地址是用来标识网络中的不同主机的,这两个源和目的端口号和IP首部中的源和目的IP地址则标识互联网上的唯一进程,所以套接字的定义说白了就是IP地址和端口号共同组成。

32位的序号
是用来标识从TCP发送端向TCP接收端发送的数据字节流的,是一个32位的无符号数。它表示在这个报文段中的的第一个数据字节在数据流中的序号。如果将字节流看作在两个应用程序间的单向流动,则TCP用序列号对每个字节进行计数。用来保证到达数据顺序的编号。
32位的确认序号
上一个字段的序号是对数据的编号,所以确认序号是下一个期望接收的TCP分段号,相当于是对对方所发送的并且已经被本方所正确接受的分段的确认。确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志为1时该确认序列号的字段才有效。所以顺序号和确认号共同作用于TCP服务中的确认,差错控制,是用于确保TCP的安全性和可靠性的。

4位的报头长度:
以32位字长为单位,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15(四位全为1)个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。不存在任选字段正常的报头长度是20字节。其实相当于给出数据在数据段中的开始位置。

保留位:占6比特,为将来的应用而保留,目前置为'0'。
编码位:占有6个比特位,他们中可以有多个为置为1,依次为:URG,ACK,PSH,RST,SYN,FIN。
 URG:该位为1说明表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
 ACK:Acknowledgement,该位为1时说明确认字段是有效,反之为0。
 PSH:请求急迫操作,这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队。
    看到这里有的读者就会产生疑问了URG和PSH都是紧急时使用,那仫这两者有什仫区别和联系呢?
    答:在一般的数据中都会存在PSH,而URG只有在紧急情况下才会触发TCP报文中的紧急指针字段,那仫什仫样的情况才是紧急情况呢?紧急方式是向对方发送紧急数据的一种方式,表示数据需要优先处理。它是一个正的偏移,与TCP首部中序号字段的值相加表示紧急数据后面的字节,紧急指针是数据最后一个字节,TCP首部中只有紧急指针指出紧急数据的位置,它所指的字节为紧急数据,但没有办法指定紧急数据的长度。
 RST:连接复位,复位因主机奔溃或其他原因而出现的错误连接,也可以用于拒绝非法的分段或拒绝连接请求
 SYN:(synchronous)是一个同步序号,通常与ACK合用用来建立连接。例如SYN=1,ACK=0表示连接请求;SYN=1,ACK=1则表示同意建立连接。
 FIN:既然有建立连接那仫必然有拆除连接,这个字段表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
16位的窗口大小:TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。这是一个16 bit字段,因而窗口大小最大为65535字节。
16位的校验和:用于对分段首部和数据进行校验。通过将所有16位的数据以补码的形式相加,然后再对相加和取补,正常情况下为0.
16位的紧急指针:只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

1.三次握手建立连接

 TCP使用三次握手来建立连接,该连接可以由任意一方发起,也可以由双方同时发起,那仫为什仫需要3次握手?每次握手都做了什仫呢?下面就来一一解决上面的问题。。。先来看三次握手建立连接的过程

 一次握手:送方首先发起TCP建立连接的请求,SYN=1,ACK=0,seq=x,此时发送方进入并进入SYN_SEND状态,等待服务器确认;

 第二次握手:接收端收到SYN,同意建立连接,SYN=1,ACK=1,ack=x+1(对发送方回应的确认字段),seq=y,此时接收端进入此时服务器进入SYN_RECV状态

 第三次握手:发送方收到接收端发来的同意建立连接的分段,如果此时确认真的要建立连接,则想接收端发送确认字段,ACK=1,ack=y+1(对接收端做出的回应)。发送方和接收方进入ESTABLISHED状态,完成三次握手。

下图是一个三次握手建立连接的简单示意图:

了解了三次握手的实现原理,下面我们就来讨论一下为什仫TCP需要3次握手建立连接,而不是2次,4次以及n次?

答:假设一下如果是两次握手建立连接会发生什仫情况呢?两次握手说明只有请求和应答,假如发送方给接收方发送了一个建立连接的请求,接收方收到了并给发送方做出了ACK应答,然而此时网络不太好,这个应答在回复的路上出了发生了阻塞,延迟了。发送方长时间未收到接收方的回应,认为建立连接失败(但是此时接收方认为连接已经建立好了),于是发送方重新给接收方发送建立连接的请求,此时延迟的ACK应答到达了发送方就会造成网络更加阻塞。而三次握手正好避免了这个问题,如果接收方的ACK应答发生延迟现象,因为是3次握手所以发送方认为自己还没有给接收方发送确认建立连接的字段,所以并不认为连接建立失败,不会重发建立连接的请求;至于为什仫不是4次,以及n次,既然3次握手已经可以成功了建立连接又为什仫要多此一举呢???(解释的比较粗糙啦!!!)

这个比较形象:

三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天balabala……”

我自己理解为双方都需要确认自己发出的消息,对方是否收到。才不会造成误解,造成资源等待浪费等情况。


四次挥手拆除连接

在上面提到了TCP的三次握手建立连接,那仫如何拆除连接呢?就是四次挥手拆除连接。因为TCP的连接时全双工的,所以拆除连接需要拆除两个单向的连接,那仫具体的拆除连接每步都做了什仫呢?详细的介绍见下文。。。

第一次挥手:当发送方的主机已经发送完毕的时候,在等待接收端的确认的同时,可以向另一端发送拆除连接的请求。FIN=1,ACK=1,seq=u;

第二次挥手:当接收端已经正确接受发送端的所有数据包,会发送一个ACK应答,同时通知本地相应的应用程序;如果此时对方要求关闭连接,此时再发送一个ACK的分段进行确认。ACK=1,FIN=0,ack=u+1;

第三次挥手:因为TCP的连接时全双工的所以也需要拆除接收方到发送方的连接,此时接收端发送一个FIN的报文段。FIN=1,ACK=1,seq=w;

第四次挥手:发送方收到这个FIN字段,发回一个ACK应答。ACK=1,FIN=0,seq=u+1,ack=w+1;
   一个TCP连接是全双工的(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭,所以正常的终止一个连接需要四次握手。收到一个FIN只意味着在这一方向上没有数据流动。一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方(即发送第一个FIN)将执行主动关闭,而另一方(收到这个FIN)执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭。
四次挥手解释:

四次挥手:
A:“喂,我不说了。”A->FIN_WAIT1

B:“我知道了。等下,上一句还没说完。Balabala…..”B->CLOSE_WAIT | A->FIN_WAIT2

B:”好了,说完了,我也不说了。”B->LAST_ACK

A:”我知道了。”A->TIME_WAIT | B->CLOSED


http://blog.csdn.net/qq_34328833/article/details/60468358