TCP三次握手和四次挥手

文章首发于个人博客地址:TCP三次握手和四次挥手
如需转载,请附带说明文章出处。

TCP数据段解析

报文在TCP连接中传输,会被分割成多个TCP段,使用IP分组承载,从一个IP地址传输到另外一个IP地址。
IP分组主要组成:

  • IP首部
    • 主要包含了源IP地址和目标IP地址
  • IP数据部分
    • TCP首部
    • TCP数据部分

这里主要对TCP首部说明一下

如下图所示:

image.png
  • 序号seq: sequence number 占用3个字节,TCP连接中传送的字节流中每个字节都按照顺序编号,使用seq表示将要传送数据的第一个字节的序号。
    • 比如一段报文携带100字节,第一个字节的序号为301,那么下一个TCP段中的序列号就应该从401开始。
  • 确认号:acknowledge number,占用4个字节,是期望收到对方下一个报文的数据字段第一个字节的序号。
    • 比如A给B发送报文,B接收到的报文其序列号为101,数据长度为200字节,则表明B收到了从101-300序号的字节,那么B给A发送ack确认号的时候,就需要将ack置为301。
  • 数据偏移: 数据偏移,占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远
  • 保留:占6位,保留今后使用,但目前应都位0;
  • URG:紧急指针是否有效。为1,表示某一位需要被优先处理。
  • ACK:仅当ACK=1时,确认号才有效。TCP规定在建立连接后,所有报文的传输都必须把ACK置为1。
  • PSH:提示接收端应用程序立即从TCP缓冲区吧数据读走。
  • RST:对方要求重新建立连接,复位。
  • SYN:请求建立连接,并在其序列号字段进行序列号的初始值时设定(seq).
    • 当SYN=1,ACK=0是表明是连接请求报文。若另一端同意,则在相应报文中应该使用SYN=1,ACK=1。
  • FIN:用来释放连接。当FIN=1时,表明此报文的发送方数据已经发送完毕,并且要求释放TCP连接。

其中关于TCP连接的建立和断开,主要需要理解SYN,ACK,FIN,seq,ack

TCP建立连接的三次握手

示意图如下:

image.png

最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。

  • 服务端进程创建传输模块TCB,时刻准备接受客户端进程的连接请求,此时服务端处于LISTEN(监听)状态。
  • 第一次握手 客户端进程创建TCB模块向服务器发送请求连接报文。
    • 报文首部中的SYN置1,选择一个初始序列号seq=x。
    • 此时客户端进入SYN-SENT(同步已发送状态)。
    • TCP规定,SYN报文段(SYN=1时)不能携带数据,但是需要消耗掉一个序号。
  • 第二次握手 TCP服务器接收到请求报文后,如果同意连接,则发出确认报文。
    • 确认报文中ACK=1,SYN=1,确认号ack=x+1(因为第一次发送的SYN报文段没有携带数据,所以ack = x+1),同时自己也初始化一个序列号seq=y。
    • 所以此时确认报文中为: SYN=1,ACK=1,ack=x+1,seq=y。
    • 此时服务器进入到SYN-RCVD(同步收到)状态。
    • 这个报文也不能携带数据,但是需要消耗一个序号。
  • 第三次握手 客户端接收到确认报文后,还需要向服务器给出确认。
    • 确认报文中ACK=1,ack=y+1,seq=x+1(因为第一次握手传递的是seq=x,而且没有携带数据,所以这一次序号就为x+1)。
    • 此时TCP连接建立,客户端进入到ESTABLISHED(已建立连接)状态。
    • TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
  • 当服务器收到客户端的确认后也进入ESTABLISHED状态,从后双方就开始通过TCP连接传输数据。

为什么客户端最后还要发送一次确认?

主要是完成两个功能:

  1. 双方都确认已经做好了发送数据的准备工作。
  2. 允许双方就初始序列号进行协商,在握手过程中被发送和确认。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果是采用三次握手的话,那一次失效的请求在到达服务端之后,服务端返回了确认报文,但是客户端没有再次发出 确认。服务器接收不到确认,那么就知道服务端并没有请求连接。

TCP断开连接的四次挥手

示意图如下:

image.png

数据传输完毕之后,双方都可以主动断开连接。断开连接前,双方都处于ESTABLISHED状态。

  • 第一次挥手 客户端进程发出连接释放报文,并且停止发送数据。
    • 释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1)。
    • 此时,客户端进入FIN-WAIT-1(终止等待1)状态。
    • TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  • 第二次挥手 服务器收到连接释放报文,发出确认报文。
    • ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时。
    • 服务端就进入了CLOSE-WAIT(关闭等待)状态。
    • TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  • 第三次挥手 客户端收到服务器的确认请求后。
    • 此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
    • 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文。
    • FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • 第四次挥手 客户端收到服务器的连接释放报文后,必须发出确认。
    • ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。
    • 注意此时TCP连接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  • 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。
    • 可以看到,服务器结束TCP连接的时间要比客户端早一些。

为什么最后客户端最后需要等待2MSL?

MSL(Maximum Segment Lifetime),意为最大报文段生存时间,TCP允许不同的实现可以设置不同的MSL值。

因为在最后客户端发出确认后,报文传送到服务端需要时间,而且也可能丢失。
如果丢失的话,那么服务端在一定时间内没有收到客户端的确认回应,可能就判断客户端没有收到我的请求,会重新向客户端发送一次,此时客户端接收到之后,会重启2MSL计时器,然后再给服务端发送确认回应。

为什么连接只需要三次,但是断开需要四次?

因为在连接时,当服务端接收到客户端的连接请求之后,将SYN和ACK放在一个报文中发送给客户端。
而关闭连接时,服务端接受到客户端发送的FIN报文时,仅仅表示客户端不会在发送数据但是还能接收数据,而自己也未必将全部数据都发送给客户端了,所以首先发送一个ACK报文确认接收到客户端的断开请求,然后等待可能没有发送完的数据发送完毕之后,再发送FIN报文给客户端,表明自己也没有数据要发送了。因为FIN报文和ACK报文一般是分开发送,从而导致多了一步。

如果已经建立连接的情况下,但是客户端出现了故障怎么办?

TCP设有一个保活计时器。当客户端出现故障之后,服务端每收到一次客户端的请求就会重新复位计时器。通常为2个小时,如果没有接收到任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若连续发送了10次都没有反应,则认为客户端出现了问题,接着 服务器端关闭连接。

end

对于网络充满了好奇,慢慢的学习,慢慢的深入,发现越来越有趣!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容