问题:TCP连接的三次握手

三次握手、四次挥手

先明确几个关键字:

同步 SYN :synchronous。建立连接,将 SYN = 1。
序号 seq :sequence。第一个字节的编号随机产生。
确认位 ACK: acknowledgement 。
ack :表示确认字段的值。
结束 FIN : finish。FIN = 1 表示希望断开连接。
重置RST:重置。

三次握手

  • 第一次握手:客户端发送同步信号 SYN 和一个随机序列号 seq = x到服务器,并进入 SYN_SEND 状态,等待服务器确认;

  • 第二次握手:服务器收到 客户端的同步信号,返回确认位 AKC = 1 ,并将传来的 x 加上 1 的ack=x+1返回
    同时自己也发送一个 同步信号SYN 和一个随机序列号 seq=y给客户端,即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;

  • 第三次握手:客户端确认收到 服务器 的同步信号SYN+ACK包,返回确认位 ACK = 1 ,并将传来的 y 加上 1 的ack=y+1返回,此时更新后的 seq = x + 1 也一并返回,此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP 连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开 TCP 连接的请求,断开过程需要经过下面提到的“四次挥手”

三次握手.gif

为什么需要三次握手呢?为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
  • 防止旧的重复连接初始化造成混乱,避免资源浪费。

谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段” 的产生在这样一种情况下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段,但是server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求,于是就向client发出确认报文段,同意建立连接。
假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了,由于client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据,但server却以为新的运输连接已经建立,并一直等待client发来数据。所以没有采用“三次握手”,这种情况下server的很多资源就白白浪费掉了。
白话一点就是,如果只有两次握手,那么:
1. A 向 B 发送了第一个请求,但是因为网络堵塞没有到达
2. 超时后,于是 A 又发送了第二个请求,这此正常到达,而且 B 回复收到了
3. A 这时就开始和 B 相互通信,并一段时间后结束了连接
4. 此时最开始的请求到达了 B,B 以为 A 又请求了连接,并且回复了 A
5. 但 A 认为自己并没有发送请求,所以并不会理睬 B, B 就只能一直等着

  • 同步双方的初始序列号

三次握手主要是为了初始化 Sequence Number,即上述中的 seq,seq的作用就是确保数据包的有序传输,数据也是通过 seq 进行数据的拼接
举例:
1. 客户端先发送了一个请求连接的数据包,初始 seq = 100 , 因为网络阻塞收不到回复,于是又发送了一个请求连接的数据包,初始 seq = 200
2. 此时网络又恢复了正常,服务端接收到了最开始发送的 seq = 100, 于是返回 ack = 101
3. 客户端比较上下文,发现自己希望收到的 ack 应该是 201,于是发送了 RST 给服务端,中止连接。
4. 一段时间后 seq = 200 到达了服务端,并返回了 ack = 201 以及自己的 seq 客户端确认信息,返回服务端的 seq + 1,建立TCP连接

第二次握手如果客户端没有收到服务端发送 SYN-ACK 报文怎么办呢?

此时服务端会进行重试,Linux 默认是等待 63s 后断开连接。
第一次等待 1 秒,第二次等待 2 秒,第三次等待 4 秒,第四次等待 8 秒,第五次等待 16 秒,再等待 32 秒后服务器会断开连接。
总共等待时间为 1 + 2 + 4 + 8 + 16 + 32 = 63 秒。

第三次握手ACK 确认包丢失怎么办

三次握手其实解决了第二步的数据包丢失问题。那么第三步的 ACK 确认丢失后,TCP 协议是如何处理的呢?

按照 TCP 协议处理丢包的一般方法,服务端会重新向客户端发送数据包,直至收到 ACK 确认为止。但实际上这种做法有可能遭到 SYN 泛洪攻击。所谓的泛洪攻击,是指发送方伪造多个 IP 地址,模拟三次握手的过程。当服务器返回 ACK 后,攻击方故意不确认,从而使得服务器不断重发 ACK。由于服务器长时间处于半连接状态,最后消耗过多的 CPU 和内存资源导致死机。

正确处理方法是服务端发送 RST 报文,进入 CLOSE 状态。这个 RST 数据包的 TCP 首部中,控制位中的 RST 位被设置为 1。这表示连接信息全部被初始化,原有的 TCP 通信不能继续进行。客户端如果还想重新建立 TCP 连接,就必须重新开始第一次握手。

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

推荐阅读更多精彩内容