TCP三次握手建立连接与四次握手终止连接及sep和ack号的正确理解

一、简介


TCP连接是面向连接的,所谓的面向连接就是,当计算机双向通信时必需先建立连接,然后才能进行数据的传输,最后还要拆除连接。而同在一个网络层的UDP传输,是面向非连接的传输,也不是可靠的。
TCP建立连接需要三次握手的过程,而拆除连接需要四次握手的过程。

二、TCP连接的建立与终止

1、TCP连接的建立(三次握手):

•在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
•第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
•第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
•第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
•完成三次握手,客户端与服务器开始传送数据.


   TCP三次握手建立连接如下图所示:




注:位码即tcp标志位,有6种标示:
SYN(synchronous建立联机) ACK(acknowledgement 确认)PSH(push传送) 
FIN(finish结束)RST(reset重置)URG(urgent紧急)

Sequence number(顺序号码) Acknowledge number(确认号码)

未连接队列:
在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN 包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器 进入ESTABLISHED状态。Backlog参数:表示未连接队列的最大容纳数目。
SYN-ACK重传次数 :
服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超 过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

注意,每次重传等待的时间不一定相同。
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

TCP选项:
每一个SYN可以含有若干个TCP选项,通常使用的选项有:
(1)MSS选项:TCP发送的SYN中,带有这个选项是通知对方它的最大分节大小MSS(maximum segment size),即它能接受的每个TCP分节中的最大数据量,可以使用TCP_MAXSEG套接口选项获取与设置这个TCP选项(Linux系统下)。
(2)窗口规模选项:TCP双方能够通知对方的最大窗口大小是65535,因为TCP头部相应的字段只占16位,这个选项指定TCP头部的广告窗口必须扩大(左移)的位数(0--14),因此所提供的最大窗口几乎是1G字节(65535*2的14次方)
(3)时间戳选项:这个这项对高速连接是必要的,它可以防止失而复得的分组可能造成的数据损坏,也就是说是暂时的路由原因造成的迷途的分组,当路由稳定后,它们又会正常到达目的地,其前提是它们在此前尚未被路由主动丢弃。

2、TCP断开连接(四次握手):

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
四次握手:
(1)TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
(4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

四次握手断开连接具体过程如下图所示:



注意:四次挥手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送. 由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记). 但在正常的TCP连接中RST包可以带ACK确认标记请注意RST包是可以不要收到方确认的。

三、TCP连接seq和ack号的正确理解

1、TCP协议结构:



2、握手阶段:

序号方向seq ack1标志位
(1) A->B10000SYN=1
(2) B->A2000010001=10000+1SYN=1, ACK=1
(3) A->B1000120001=20000+1ACK=1

解释
(1)A向B发起连接请求,以一个随机数初始化A的seq,这里假设为10000,此时ACK=0
(2)B收到A的连接请求后,也以一个随机数初始化B的seq,这里假设为20000,意思是:你的请求我已收到,我这方的数据流就从这个数开始。B的ACK是A的seq加1,即10000+1=10001
(3)A收到B的回复后,它的seq是它的上个请求的seq加1,即10000+1=10001,意思也是:你的回复我收到了,我这方的数据流就从这个数开始。A此时的ACK是B的seq加1,即20000+1=20001


3、挥手阶段:

序号方向seq ack1标志位
(1) A->B1000120001FIN=1, ACK=1
(2) B->A10002=10001+1ACK=1
(3) B->A2000110002=10001+1FIN=1, ACK=1
(4) A->B20002ACK=1

解释
(1)A向B发起断开连接请求,A的seq为之前的值10001没变,此时ACK也为上一次的值20001没变;
(2)B收到A的断开连接请求后,向A发送确认断开连接,ACK为A的seq加1,即10001+1=10002,同事ACK标志位置1,意思是:你的主动断开连接请求我已收到,将关闭从A到B的数据传送;
(3)B向A发送断开连接请求,它的seq是A的ACK,即20001;
(4)A收到B的断开连接请求后,向B发送确认断开连接,ACK为B的seq加1,即20001+1=20002,同事ACK标志位置1,意思是:你的主动断开连接请求我已收到,将关闭从B到A的数据传送;

4、数据传送阶段:

序号方向seq ack1size
(1) A->B40007000100
(2) B->A70004100=4000+10054
(3) A->B41007054=7000+54100
(4) B->A70544200=4100+100 54

解释:
(1)B接收到A发来的seq=4000,ack=7000,size=100的数据包
(2)于是B向A也发一个数据包,告诉B,你的上个包我收到了。B的seq就以它收到的数据包的ACK填充,ACK是它收到的数据包的SEQ加上数据包的大小(不包括以太网协议头,IP头,TCP头),以证实B发过来的数据全收到了。
(3)A 在收到B发过来的ack为4100的数据包时,一看到4100,正好是它的上个数据包的seq加上包的大小,就明白,上次发送的数据包已安全到达。于 是它再发一个数据包给B。这个正在发送的数据包的seq也以它收到的数据包的ACK填充,ACK就以它收到的数据包的seq(7000)加上包的 size(54)填充,即ack=70000+54(全是头长,没数据项)。
(4)B向A也发一个数据包,B的seq就以它收到的数据包的ACK填充,ACK是它收到的数据包的SEQ(4100)加上数据包的大小100(不包括以太网协议头,IP头,TCP头);
其实在握手和结束时确认号应该是对方序列号加1,传输数据时则是对方序列号加上对方携带应用层数据的长度.如果从以太网包返回来计算所加的长度,就嫌走弯路了.
另外,如果对方没有数据过来,则自己的确认号不变,序列号为上次的序列号加上本次应用层数据发送长度.


四、为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的.


本文参考资料来自:

http://blog.chinaunix.net/uid-25513153-id-187780.html

http://blog.chinaunix.net/uid-20788636-id-1841260.html

位码即tc标志位,6种标示:

SYN(synchronous建立联机)      ACK(acknowledgement确认) PSH(push传送)                          FIN(finish结束)

RST(reset重置)                          URG(urgent紧急)

Sequence number(顺序号码)    Acknowledge number(确认号码)

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值