TCP握手与挥手

技术革命

格雷厄姆在《黑客与画家》中提到一个观点,历史上财富的积累无非两种方式---偷窃和抢夺。新技术革命的出现,财富的积累的新方式则是技术进步。

技术进步创造了无数的财富,而这个技术指的就是网络技术。相对于人类的文明,网络的历史如同昙花一现,恰恰是这么短的时间内,所创造的文明和财富却是前所未有。相对于网络自身的发展,其实已经算是历史悠久了。然而自从网络诞生到现在,网络的基础架构理论,基本的通信协议改变也不是很大。

我们所熟知的Internet,把全世界的人连接起来,Inernet构建于TCP/IP模型基础之上。TCP/IP模型有着很多协议,其中与网络(web)应用开发者息息相关的莫过于TCP协议。想要了解TCP协议的本质,起始于TCP的三次握手和四次挥手。

TCP 握手连接

连接是一个通信的行为。建立连接,就能使用连接进行通信。连接作用于两个节点。TCP是有状态的协议,因此两个节点之间想要通过tcp发送数据,必须先建立可靠有效的连接。tcp是双通道的通信模式,因此tcp的连接(逻辑连接)其实是两条物理连接,即客户端-->连接服务端--->客户端的连接。

Handshake.png

上图即是经典的TCP三次握手。握手前,服务端创建socket对象,绑定地址,开启监听;客户端创建socket,准备连接。然后进行三次握手连接:

  1. clinet向server端发送一个[SYN]包,seq=x。
  2. server收到[SYN]包之后,向clinet发送[SYN ACK] seq=y,ack=x+1
  3. clinet收到server的syn和ack之后,再向server端发送[ACK] ack=y+1包,至此三次握手完成。

创建一个tcp连接,通过三次握手即可。其实三次握手的clinet和server端是在不同的变化状态。下面详细讨论下三次握手中的两端的状态变化。

TCP 握手c/s端状态

针对三次握手的详细过程,有如下过程:

  1. 发起握手的时候,clinet发送[SYN]包之后,自身马上变成SYN_SENT状态,server则是进行了listen,自身的状态则变成LISTEN。接受到[SYN]包之后,自身变成SYN_RCVD状态。这个过程主要含义是clinet向server建立一条发送数据的连接。

  2. server端收到了client的SYN之后,马上会发送一个[SYN ACK]包,这里一共有两个作用。ACK用于应答client,表示client->server的连接已经建立,同时server也想向client建立一条发送数据的连接,因此也需要发送一个[SYN]包。

  3. client收到了server的[SYN ACK]。通过server发的ACK确定了client->server这条连接建立。自身状态变成了ESTABLISHED,表示可以正常的发送数据给server了。同时为了响应server发送的建立连接的SYN请求,再次给server做一次ACK的应答,一旦server收到clinet的ACK应答,server的状态也会变成ESTABLISHED

上述的过程中涉及到几个状态,其中SYN_SENTSYN_RCVD非常短暂,使用nc等工具也很难看到这种状态的。syn包表示希望建立一个连接,ack包表示应答。连接的本质是:

    client  ----- 发送syn ------>  server  希望创建连接
    client  <----- 发送ack ------  server  确定创建连接

之所以是三次握手,而不是第四次握手,是因为第二次握手的时候,server把 [SYN] 和 [ACK]一起发送了。

客户端 服务端
开始状态 过程 结束状态 开始状态 过程 结束状态
CLOSED client创建socket CLOSED CLOSED server创建socket,绑定地址,打开监听 LISTEN
CLOSED [第一次握手]client向server发送SYN包 SYS-SENT LISTEN 等待client发送的SYN LISTEN
SYS-SENT 发送syn之后等待server发送ack SYS-SENT LISTEN [第二次握手]接受client的syn,同时向client发送[SYN ACK] SYN-RECEIVED
SYN-SENT 接受server的SYN+ACK,通过ack确定client->server连接创立,[第三次握手]同时针对SYN发送ACK ESTABLISHED SYN-RECEIVED 等待clinet发送的ACK确认 SYN-RECEIVED
ESTABLISHED 等待server完成对ack的响应,等待完成server->clinet的连接 ESTABLISHED SYN-RECEIVED 接受client的ACK确定,完成server->clinet的连接 ESTABLISHED
ESTABLISHED 发送接受数据 ESTABLISHED ESTABLISHED 发送接收数据 ESTABLISHED

参考

TCP 挥手断连

了解了tcp的握手方式,那么挥手方式就很容易理解啦。与创建连接syn不一样,想要端口连接需要发送的是fin包。同样为了确定断开连接,需要发送ack应答确认包。大概方式入下图:

Termination.png

断开tcp需要四步,断开连接既可以是client主动,server被动,也可以server主动断开。两种的状态变化也是相对而言。下面以client主动断开为例:

  1. client发送[FIN]包,表示要断开clinet->server的连接。
  2. server收到[FIN]之后,发送一个[ACK]包表示确定断开连接啦。
  3. 同时server也会向clinet再发一个[FIN]包,表示也想断开server->clinet的连接。
  4. clinet收到server的[ACK]包,确定了clinet->server的连接的断开,该连接将不会发送数据啦。由于client也会收到server的[FIN]包,因此也要为断开server->clinet的连接发送[ACK]给server确定。

至此,四次挥手完成。下面详细四次交互过程两个端的状态。

client和server端传送数据的时候,双方的状态都是ESTABLISHED。一旦clinet发送了fin之后,自身变成FIN-WAIT-1的状态,意思是等待server端的ack确定。此时,该通道不再向server发送数据,但是仍然可以接收server数据了。

server收到了clinet发送的ack之后,自身的状态由ESTABLISHED变成CLOSE_WAIT。client收到ack后,自身由FIN-WAIT-1变成FIN-WAIT-2,断开了连接。此时client在等待server端的fin信号。

server 发送 ack之后,自身就由CLOSE_WAIT变成LAST-ACK状态,即等待client的最后的ack确定。client收到server的fin包之后,自身就由 FIN-WAIT-2 变成 TIME_WAIT状态,等待一个2MSL时间之后,就变成了CLOSED状态。

最后server收到client的ack确定之后,自身也变成CLOSED状态。

客户端 服务端
开始状态 过程 结束状态 开始状态 过程 结束状态
ESTABLISHED 向server发送FIN,表示想关闭clinet->server的连接 FIN-WAIT-1 ESTABLISHED 正常服务,直到收到FIN ESTABLISHED
FIN-WAIT-1 发送完毕FIN,等待server的确认应答,此时将不会再发送数据给server FIN-WAIT-1 ESTABLISHED 接受FIN,发送ACK确认断开连接 CLOSE-WAIT
FIN-WAIT-1 接收server发送的ACK,确定client->server连接关闭 FIN-WAIT-2 CLOSE-WAIT 发送FIN,表示关闭server->client的连接 LAST-ACK
FIN-WAIT-2 收到server的FIN包,发送ACK作为应答 TIME-WAIT LAST-ACK 等待 client发送的ACK LAST-ACK
TIME-WAIT 等待MSL时间,保证ACK能被对方收到,等待fin否则重发 TIME-WAIT LAST-ACK 接受ACK应达,关闭server->clinet的连接 CLOSED
TIME-WAIT MSL 时间过期 CLOSED CLOSED 连接关闭 CLOSED

参考

问题

三次握手保证了TCP连接的可靠性,假设没有三次握手只有两次。如果client发送第一个syn的时候延迟很大,导致client发送了第二个,第二个syn很快就到达server端。于是server发送ack确定连接,并发送syn。在两次握手的情况下,服务器认为连接都建立好了。如果此时第一个syn又抵达了服务器,那么服务器将会再次应答,向client端发送连接请求。这样会造成无效的连接,通过第三次握手,可以在server应答无效连接的时候提前终止。也就是最后一次握手不再发送ack,那么server就不会再创建连接。

在关闭连接的时候,虽然两个端都统一关闭连接,并且四次交互也发送完毕。假设如果网络延迟很大,或者丢包严重,就很难保证client最后一次ack一定能被server收到。如果server收不到,会重发fin。为了解决这个问题,通常在client发送ack之后2MSL时间,才由TIME_WAIT变成CLOSED状态,在此期间,client可以针对server补发的fin重发ack。

还有一个CLOSING状态,这个状态表示client发送了FIN之后,并没有收到ACK,反而先收到了server的FIN。当然这种情况十分罕见的“异常”状态。双方都同时关闭连接,有可能在四次交互的时候,出现某些包延迟。

总结

TCP 连接和断开的过程中,都是一问一答的方式,创建连接的问是syn,回答是ack,同样断开连接的问是fin,回答是ack。有问必有答,那么连接就能正常的创建和关闭。因为tcp通信是双通道的,因此一个TCP逻辑连接,实际上是两条成对client和server端的物理连接。无论连接和断开,都需要把这两个连接都处理完毕才能完成。也因为这两个过程,中间衍生出了很多状态。这些状态在创建连接的时候有client和server端的区分,在断开的连接的时候就没有特别区别,只有主动断开和被动断开的差别。

至于tcp三次握手中两端的“两个连接”的通信通道,他们的具体原理和过程,我们将会在TCP连接与Python中详细讨论。

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

推荐阅读更多精彩内容