TCP的3次握手和4次挥手协议及数据传输过程

  1. TCP建立连接3次握手

    握手过程如下:

    1. 客户端A向服务器发送TCP连接请求数据包,报文设置同步标志位SYN=1,客户端序号seq=x(表明传输数据时的第一个数据字节的序号是x),A然后进入SYN-SENT状态;

    2. 服务器B收到连接请求后,发回连接确认数据包,报文设置同步标志位SYN=1,服务端序号seq=y,以及对客户端的确认号ack=seq(A)+1=x+1,B然后接入SYN-RCVD状态;

    3. 客户端A收到服务器B的确认数据包后,进一步做确认,发送一个SYN=0,seq=x+1,ack=seq(B)+1=y+1的确认报文,A然后进入数据传输状态ESTABLISHED,服务器B收到客户端A的确认报文后也进入数据传输状态ESTABLISHED;


      连接流程

    那为什么只是3次握手呢?
    举个随便找人聊天的例子:

      A对B说:喂,你听得到我说话吗?
      B对A回:嗯,我听到的你说话,你听得到我说话吗?
      A回B说:可以听到,我们开始聊天把!
      BABALA的聊天
    

    应该把网络状态想象为不可靠的,3次握手可以保证任何一次握手出现问题都可以发现或补救:

    1. 第一次握手A发送SYN传输失败,A,B都不会申请资源,连接失败。如果一段时间内发出多个SYN连接请求,那么B只会接受它最后发送的那个SYN的SYN+ACK回应,忽略其他回应全部回应,B中多申请的资源也会释放;

    2. 第二次握手B发送SYN+ACK传输失败,A不会申请资源,B申请了资源,但收不到A的ACK,过一段时间释放资源。如果是收到了多个A的SYN请求,B都会回复SYN+ACK,但A只会承认其中它最早发送的那个SYN的回应,并回复最后一次握手的ACK;

    3. 第三次握手ACK传输失败,B没有收到ACK,释放资源,对于后序的A的传输数据返回RST。实际上B会因为没有收到A的ACK会多次发送SYN+ACK,次数是可以设置的,如果最后还是没有收到A的ACK,则释放资源,对A的数据传输返回RST。

  2. 数据传输

  3. TCP释放连接4次握手

    四次握手过程如下:

    1. 客户端A主动关闭连接,A发送一个终止标志位FIN=1,客服端序号seq=u的数据包到服务器B,然后A进入FIN-WAIT-1状态,表示A没有数据要传输给服务器B,此时A处于半连接状态;

    2. 服务器B收到FIN数据包,就返回一个ACK,同意关闭连接,seq=v,确认号ack=u+1,此时服务端B进入CLOSE-WAIT状态;

    3. 客户端A收到这个数据包后,进入FIN-WAIT-2状态,此时仍然可以接收服务器B发送过来的数据包;

    4. 服务器B没有数据数据要传输给客户端A,也发送一个一个终止标志位FIN=1,seq=w,ack=u+1的确认数据包,尔后进入LAST-ACK状态。客户端A收到服务器B的FIN关闭确认数据包后,给服务器B发回一个确认包,seq=u+1,ack=w+1,进入TIME-WAIT状态,等待2MSL时间后进入CLOSED状态,服务器B接收到客户端的ACK确认报文后进入CLOSED关闭状态,此时服务器B若没有收到这个ACK,服务器B的超时重传机制会重新发送一个关闭确认数据包。


      释放流程

    问答:

    1. 那为什么是4次握手呢?
      答:因为TCP是全双工通信,每个方向上都要进行单独关闭,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

    2. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间 Maximum Segment Lifetime)才能返回到CLOSE状态?
      答:

      1. 为了保证主动关闭方的最后一个ACK报文能够到达被动关闭方,假设这个ACK报文丢失了,处于LAST-ACK状态的被动关闭方在规定的时间内没有收到这个ACK报文,或超时重传FIN报文,而主动关闭方在等待2MSL时间内收到这个重传的报文会重新回复一次确认,重新启动2MSL计时器。如果主动关闭方在TIME-WAIT状态内不等待2MSL的话,就无法收到重传报文。
      2. 主动关闭方在等待2MSL时间后,可以使得本连接持续时间每产生的所有报文都过期了,使得下一次新的连接不会出现旧的连接报文。
    3. 为什么会出现大量的CLOSE-WAIT状态的连接,如何解决?
      答:

      1. 产生原因
        • CLOSE_WAIT产生的原因是主动关闭方主动关闭,被动关闭方收到FIN包,应用层却没有做出关闭操作引起的。也就是说,在被动关闭连接情况下,在已经接收到FIN,但是还没有发送自己的FIN的时刻,连接处于CLOSE_WAIT状态。
        • 出现大量CLOSE_WAIT的现象,主要原因是某种情况下对方关闭了socket链接,但是我方忙与读或者写,没有关闭连接。
      2. 解决方案
        • 通过优化系统内核参数可容易解决
          vi /etc/sysctl.conf 
          #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
          net.ipv4.tcp_keepalive_time=1200   
          #生效,如下命令 
          /sbin/sysctl -p
          
        • 需要从程序本身出发
        • 可以使用TCP的keepalive功能,让操作系统替我们自动清理掉CLOSE_WAIT连接
    4. 为什么会出现大量的TIME-WAIT状态的连接,如何解决?
      答:

      • 产生原因
        在通讯过程中A主动关闭造成的, 在A发送了最后一个FIN包后,系统会等待 Double时间 的MSL(Max Segment Lifetime)【注:按不同的操作系统有不同时间】用于等待接受B发送过来的FIN_ACK和FIN, 这段时间A的对应的socket的fd是不能够重新利用的, 这样在大量的短连接服务中,会出现TIME_WAIT过多的现象。
      • 解决方法
        1. 通过优化系统内核参数,调整TIME_WAIT超时时间

          vi /etc/sysctl.conf 
          #表示开启SYN Cookies。 
          #当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭 
          net.ipv4.tcp_syncookies = 1 
          #表示开启重用。 
          #允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 
          net.ipv4.tcp_tw_reuse = 1 
          #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭 
          net.ipv4.tcp_tw_recycle = 1 
          #表示如果套接字由本端要求关闭。 
          #这个参数决定了它保持在FIN-WAIT-2状态的时间 
          #生效,如下命令 
          /sbin/sysctl -p
          
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容