TCP传输控制协议是面向链接的可靠的传输层协议,在进行数据传输以前,须要在传输数据的两端(客户端和服务器端)建立一个链接,这个链接由一对插口地址惟一标识,便是在IP报文首部的源IP地址、目的IP地址,以及TCP数据报首部的源端口地址和目的端口地址。TCP首部结构以下:安全
其中在TCP链接和断开链接过程当中的关键部分以下:服务器
1.源端口号:即发送方的端口号,在TCP链接过程当中,对于客户端,端口号每每由内核分配,无需进程指定;网络
2.目的端口号:即发送目的的端口号;并发
3.序号:即为发送的数据段首个字节的序号;.net
3.确认序号:在收到对方发来的数据报,发送确认时期待对方下一次发送的数据序号;blog
4.SYN:用于发送链接请求;进程
5.ACK:确认序号有效;事件
6.FIN:断开链接。资源
三次握手的过程以下:随机数
step1. 由客户端向服务器端发起链接请求。发送请求标识位SYN置为1,发送序号为一个随机数,这里假设为X;
step2. 服务器端接收到链接请求,将标识位ACK置为1,并将确认序号置为X+1,而后生成一个随机数Y做为发送序号(由于所确认的数据报的确认序号未初始化);
step3: 客户端对接收到的确认进行确认,将确认序号置为Y+1,而后将发送序号置为X+1(即为接收到的数据报的确认序号);
这里有几点须要说明一下:
1.为何是三次握手而不是两次。对于step3的做用,假设一种状况,客户端A想服务器B发送一个链接请求数据报,而后这个数据报在网络中滞留致使其迟到了,虽然迟到了,可是服务器仍然会接收并发回一个确认数据报。可是A却由于久久收不到B的确认而将发送的请求链接失效,等到一段时间后,接到B发送过来的确认,A认为本身如今没有发送链接,而B却一直觉得链接成功了,因而一直在等待A的动做,而A将不会有任何的动做了。这会致使服务器资源白白浪费掉了,所以,两次握手是不行的,所以须要再加上一次,对B发过来的确认再进行一次确认,即确认此次链接是有效的,从而创建链接。
2.对于双方,发送序号的初始化为什么值。有的系统中是显式的初始化序号是0,可是这种已知的初始化值是很是危险的,由于这会使得一些黑客钻漏洞,发送一些数据报来破坏链接。所以,初始化序号由于取随机数会更好一些,而且是越随机越安全。
下面是一个简单的客户端/服务器端链接程序,在Linux环境下,开启三个终端,在第一个终端输入命令
而后在第二个终端运行服务器端程序:
最后在第三个终端运行客户端程序:
完了以后,咱们能够在第一个终端看到抓包的结果,以下:
前三个数据包就是三次握手的三个数据报了。咱们逐个分析一下,第一个数据报是由客户端发送到服务器端,随机产生一个序号seq = 830831828。而后第二个数据报是由服务器端发回的确认,随机产生一个序号seq = 2690963443,而后根据接收到的请求数据报将确认序号设置为830831829。而后第三个数据报是有客户端对服务器端确认数据报的确认,能够看出确认序号为2690963444
链接双方在完成数据传输以后就须要断开链接。因为TCP链接是属于全双工的,即链接双方能够在一条TCP链接上互相传输数据,所以在断开时存在一个半关闭状态,即有有一方失去发送数据的能力,却还能接收数据。所以,断开链接须要分为四次。主要过程以下:
主要过程以下:
step1. 主机A向主机B发起断开链接请求,以后主机A进入FIN-WAIT-1状态;
step2. 主机B收到主机A的请求后,向主机A发回确认,而后进入CLOSE-WAIT状态;
step3. 主机A收到B的确认以后,进入FIN-WAIT-2状态,此时即是半关闭状态,即主机A失去发送能力,可是主机B却还能向A发送数据,而且A能够接收数据。此时主机B占主导位置了,若是须要继续关闭则须要主机B来操做了;
step4. 主机B向A发出断开链接请求,而后进入LAST-ACK状态;
step5. 主机A接收到请求后发送确认,进入TIME-WAIT状态,等待2MSL以后进入CLOSED状态,而主机B则在接受到确认后进入CLOSED状态;
这里有几点须要说明:
1. 为什么主机A在发送了最后的确认后没有进入CLOSED状态,反而进入了一个2MSL的TIME-WAIT。主要做用有两个:第一,确保主机A最后发送的确认可以到达主机B。若是处于LAST-ACK状态的主机B一直收不到来自主机A的确认,它会重传断开链接请求,而后主机A就能够有足够的时间去再次发送确认。可是这也只能尽最大力量来确保可以正常断开,若是主机A的确认老是在网络中滞留失效,从而超过了2MSL,最后也没法正常断开;第二,若是主机A在发送了确认以后当即进入CLOSED状态。假设以后主机A再次向主机B发送一条链接请求,而这条链接请求比以前的确认报文更早地到达主机B,则会使得主机B觉得这条链接请求是在旧的链接中A发出的报文,并不当作是一条新的链接请求了,即便得这个链接请求失效了,增长2MSL的时间可使得这个失效的链接请求报文做废,这样才不影响下次新的链接请求中出现失效的链接请求。
2. 在下面的抓包实验中,为何断开链接请求报文只有三个,而不是四个。由于在TCP链接过程当中,确认的发送有一个延时(即经受延时的确认),一端在发送确认的时候将等待一段时间,若是本身在这段事件内也有数据要发送,就跟确认一块儿发送,若是没有,则确认单独发送。而咱们的抓包实验中,由服务器端先断开链接,以后客户端在确认的延迟时间内,也有请求断开链接须要发送,因而就与上次确认一块儿发送,所以就只有三个数据报了。
http://blog.csdn.net/hulifangjiayou/article/details/47283387