tcp连接断讲义开过程
TCP连接断开机制(笔记二)

TCP连接断开机制(笔记⼆)
⼀、三次握⼿过程
为什么要三次握⼿?
⽬的:建⽴可靠的通信信道,双⽅确认⾃⼰与对⽅的数据发送与接收是正常的。
Server端处于监听状态,双⽅的数据收发是串⾏的。
第⼀次:Client什么都不能确认;Server能确认对⽅发送正常,⾃⼰接收正常。
第⼆次:Client确认⾃⼰和对⽅发送,接收正常,Server确认对⽅发送正常,⾃⼰接收正常。
第三次:Client确认⾃⼰和对⽅发送,接收正常,Server确认⾃⼰和对⽅发送,接收正常。
⼆、TCP数据传输
TCP协议负责保障⽹络数据包的可靠性,使⽤确认技术来确保⽬的设备收到了从源设备发来的数据,并且是准确⽆误的。
为保证数据传输的可靠性,TCP协议做的底层⼯作:数据分割,排序编号,校验和,去重,流量控制,拥塞控制,ARQ协议,超时重传。
三、TCP挥⼿机制
为什么要四次挥⼿?
TCP连接时两端可以同时接收和发送数据,因此每个端都必须要单独进⾏关闭,主要⽬的是为了可靠的通信。
Client表⽰没有数据发送了,但是还能接收来⾃Server的数据。
Server告诉Client你的意思我知道了,但是我还能发送数据给你,整个连接处于半关闭了。
Server数据发送完毕,告诉Client我也可以关闭连接了。
你的数据我接收完了,都关闭连接吧。
注:中间少⼀次,都会造成数据传输的不可靠。
问题:为什么第⼆次,第三次挥⼿不能合并为⼀次?。
tcp连接与断开连接图解

tcp连接与断开连接图解
建立连接非常重要,它是数据正确传输的前提;断开连接同样重要,它让计算机释放不再使用的资源。
如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。
建立连接需要三次握手,断开连接需要四次握手,可以形象的比喻为下面的对话:[Shake 1]套接字A:任务处理完毕,我希望断开连接。
[Shake 2]套接字B:哦,是吗?请稍等,我准备一下。
等待片刻后
[Shake 3]套接字B:我准备好了,可以断开连接了。
[Shake 4]套接字A:好的,谢谢合作。
下图演示了客户端主动断开连接的场景:
建立连接后,客户端和服务器都处于ESTABLISED状态。
这时,客户端发起断开连接的请求:
1)客户端调用close()函数后,向服务器发送FIN 数据包,进入FIN_WAIT_1状态。
FIN 是Finish 的缩写,表示完成任务需要断开连接。
2)服务器收到数据包后,检测到设置了FIN 标志位,知道要断开连接,于是向客户端发送确认包,进入CLOSE_WAIT状态。
注意:服务器收到请求后并不是立即断开连接,而是先向客户端发送确认包,告诉它我知道了,我需要准备一下才能断开连接。
3)客户端收到确认包后进入FIN_WAIT_2状态,等待服务器准备完毕后再次发送数据包。
4)等待片刻后,服务器准备完毕,可以断开连接,于是再主动向客户端发送FIN 包,告诉它我准备好了,断开连接吧。
然后进入LAST_ACK状态。
5)客户端收到服务器的FIN 包后,再向服务器发送ACK 包,告诉它你断开连接吧。
tcp连接断开过程

fork parent
child process
继续上次的例子
Client process
Server
process
shutdown
tcp协议栈
FIN ACK
FIwn
end
end
三次握手的数据包
内容简介
• 简介 • 正常流程 • 异常处理 • 其他问题
异常处理
• 报文丢失
FIN报文和ACK报文的丢失
• 异常报文到达
CLOSE_WAIT、FIN_WAIT2和TIME_WAIT状态下的处理
报文丢失 -- FIN报文(1)
主动关闭方 FIN_WAIT1
FIN
rto
FIN
2rto
FIN
被动关闭方
报文丢失 -- FIN报文(2)
主动关闭方
ACK
FIN_WAIT2
AbortOnTimeout 重传超时
AbortOnSyn AbortOnLinger
收到异常的SYN报文,报文序号大于期望的报文序 号
tcp_linger2为负值
Thanks Q&A
FIN_WAIT2 TIME_WAIT
被动关闭方
ESTABLISHED
FIN
ACK
CLOSE_WAIT
FIN
LAST_ACK
ACK
CLOSED
上次的例子
Client
Start
socket
connect process
Server
Start
SYN SYN,ACK
ACK
socket bind listen
不复用
能够复用
开启tcp_tw_recyle
TCP连接与断开详解(socket通信)

TCP连接与断开详解(socket通信)⼀、TCP数据报结构以及三次握⼿TCP(Transmission Control Protocol,传输控制协议)是⼀种⾯向连接的、可靠的、基于字节流的通信协议,数据在传输前要建⽴连接,传输完毕后还要断开连接。
客户端在收发数据前要使⽤ connect() 函数和服务器建⽴连接。
建⽴连接的⽬的是保证IP地址、端⼝、物理链路等正确⽆误,为数据的传输开辟通道。
TCP建⽴连接时要传输三个数据包,俗称三次握⼿(Three-way Handshaking)。
可以形象的⽐喻为下⾯的对话:[Shake 1] 套接字A:“你好,套接字B,我这⾥有数据要传送给你,建⽴连接吧。
”[Shake 2] 套接字B:“好的,我这边已准备就绪。
”[Shake 3] 套接字A:“谢谢你受理我的请求。
”TCP数据报结构我们先来看⼀下TCP数据报的结构:带阴影的⼏个字段需要重点说明⼀下:1) 序号:Seq(Sequence Number)序号占32位,⽤来标识从计算机A发送到计算机B的数据包的序号,计算机发送数据时对此进⾏标记。
2) 确认号:Ack(Acknowledge Number)确认号占32位,客户端和服务器端都可以发送,Ack = Seq + 1。
3) 标志位:每个标志位占⽤1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN,具体含义如下:URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收⽅应该尽快将这个报⽂交给应⽤层。
RST:重置连接。
SYN:建⽴⼀个新连接。
FIN:断开⼀个连接。
对英⽂字母缩写的总结:Seq 是 Sequence 的缩写,表⽰序列;Ack(ACK) 是 Acknowledge 的缩写,表⽰确认;SYN是 Synchronous 的缩写,愿意是“同步的”,这⾥表⽰建⽴同步连接;FIN 是 Finish 的缩写,表⽰完成。
TCP断开连接的过程

TCP断开连接的过程黄⾊框线⾥⾯表⽰客户端请求关闭连接。
补充细节(来⾃⽹络):关于以上的四次握⼿,我补充下细节:1. 默认情况下(不改变socket选项),当你调⽤close( or closesocket,以下说close不再重复)时,如果发送缓冲中还有数据,TCP会继续把数据发送完。
2. 发送了FIN只是表⽰这端不能继续发送数据(应⽤层不能再调⽤send发送),但是还可以接收数据。
3. 应⽤层如何知道对端关闭?通常,在最简单的阻塞模型中,当你调⽤recv时,如果返回0,则表⽰对端关闭。
在这个时候通常的做法就是也调⽤close,那么TCP层就发送FIN,继续完成四次握⼿。
如果你不调⽤close,那么对端就会处于FIN_WAIT_2状态,⽽本端则会处于CLOSE_WAIT状态。
这个可以写代码试试。
4. 在很多时候,TCP连接的断开都会由TCP层⾃动进⾏,例如你CTRL+C终⽌你的程序,TCP连接依然会正常关闭,你可以写代码试试。
---------------------------------下⾯来⾃⽹络-------------------------------------------------------------TCP状态转移要点TCP协议规定,对于已经建⽴的连接,⽹络双⽅要进⾏四次握⼿才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本⾝占⽤的资源不会被释放。
⽹络服务器程序要同时管理⼤量连接,所以很有必要保证⽆⽤连接完全断开,否则⼤量僵死的连接会浪费许多服务器资源。
在众多TCP状态中,最值得注意的状态有两个:CLOSE_WAIT和TIME_WAIT。
1、LISTENING状态 FTP服务启动后⾸先处于侦听(LISTENING)状态。
2、ESTABLISHED状态 ESTABLISHED的意思是建⽴连接。
表⽰两台机器正在通信。
3、CLOSE_WAIT对⽅主动关闭连接或者⽹络异常导致连接中断,这时我⽅的状态会变成CLOSE_WAIT 此时我⽅要调⽤close()来使得连接正确关闭4、TIME_WAIT我⽅主动调⽤close()断开连接,收到对⽅确认后状态变为TIME_WAIT。
TCP的建立连接过程和断开过程

TCP的建立连接过程和断开过程TCP(Transmission Control Protocol,传输控制协议)是一种基于连接的、可靠的传输层协议,用于在网络中的两个应用程序之间建立连接和传输数据。
1.TCP建立连接过程(三次握手):当客户端想要与服务器建立连接时,TCP使用三次握手来确保双方都准备好进行通信。
步骤1:客户端向服务器发送一个特殊的TCP报文段,称为SYN(同步)报文段。
SYN报文段中包含一个初始序列号(ISN)。
步骤2:服务器收到SYN报文段后,会发送一个确认报文段SYN-ACK 给客户端。
SYN-ACK报文段中包含确认号(与ISN相同)和服务器的初始序列号(ISN)。
步骤3:客户端收到SYN-ACK报文段后,再发送一个确认报文段ACK 给服务器。
ACK报文段中的确认号是服务器的初始序列号加1这样,客户端和服务器之间就建立起了连接,可以开始传输数据。
2.TCP断开连接过程(四次挥手):当客户端或服务器想要断开连接时,TCP使用四次挥手来确保双方都关闭了连接。
步骤1:客户端向服务器发送一个特殊的TCP报文段,称为FIN(结束)报文段。
该报文段表示客户端已经完成了数据的发送,但仍然接收数据。
步骤2:服务器收到FIN报文段后,会发送一个确认报文段ACK给客户端,表示已经接收到了FIN报文段。
步骤3:服务器发送一个特殊的TCP报文段,称为FIN报文段,表示服务器已经完成了数据的发送。
步骤4:客户端收到服务器的FIN报文段后,会发送一个确认报文段ACK给服务器,表示已经接收到了FIN报文段。
这样,客户端和服务器之间的连接就完全关闭了。
3.TCP建立连接过程的详细分析:-客户端发送一个带有SYN标志的TCP报文段给服务器,该报文段中包含一个随机生成的初始序列号(ISN)。
-服务器收到报文段后,生成一个自己的ISN,并发送一个带有SYN 和ACK标志的报文段给客户端。
该报文段中包含确认号(与客户端的ISN 相同)和服务器的ISN。
图解TCP建立连接全过程

CP客户端,B是服务端。最初两端的TCP进程都处于 CLOSED状态。图中在主机下面的是TCP进程所处的状态。 A是主动打开连接,B是被动打开连
接。 首先A向B发出连接请求报文段,这时首部中的同步位 SYN=1,同时选择一个初始序号seq=x。TCP规定,SYN报 文段不能携带数据,但
要消耗掉一个序号。这时,A进入SYN-SENT状态。 B收到请求后,向A发送确认。在确认报文段中把SYN和 ACK位都置为1,确认号是ack
=x+1,同时也为自己选择一个初始序号seq=y。请注意,这 个报文段也不能携带数据,但同样要消耗掉一个序号。 这时B进入SYN-RCVD状态。
A收到B的确认后,还要向B给出确认。确认报文段的ACK 置为1,确认号ack=y+1,而自己的序号seq=x+1。这时, TCP连接已经建立
Hale Waihona Puke 发出的第一个请求报文段并未丢失,而是在某个网络节 点长时间滞留了,以致延误到连接释放以后的某个时间 才到达B。本来这是一个早已失效的报文段。但B
收到此失效的连接请求报文段后,就误以为A又发了一次 新的连接请求,于是向A发出确认报文段,同意建立连接。 假如不采用三次握手,那么只要B发出确认
,新的连接就建立了。 由于A并未发出建立连接的请求,因此不会理睬B的确认, 也不会向B发送数据。但B却以为新的运输连接已经建立 了,并一直等待
,A进入ESTABLISHED状态,当B收到A的确认后,也会进 入ESTABLISHED状态。 以上给出的连接建立过程就是常说的TCP三次握
手。 为什么A还要发送一次确认呢?这主要是为了防止已失效 的连接请求报文段突然又传送到了B,因而产生错误。 所谓已失效的连接请求报文段是这
TCPIP网络协议总结(二)传输层协议之TCP连接的建立与断开

TCPIP⽹络协议总结(⼆)传输层协议之TCP连接的建⽴与断开前⾯已经介绍了了TCP/IP协议栈,⽹络数据帧/报/段结构,TCP连接等⽹络通讯基础知识,这⼀篇⽂章我来总结⼀下TCP协议:1.TCP的连接的建⽴2.TCP三次握⼿ 握⼿为什么是3次⽽不是2次或4次; SYN攻击;3.TCP断开连接,四次挥⼿; TIME_WAIT状态;1.TCP三次握⼿和四次挥⼿的过程:三次握⼿的过程:1次握⼿:由客户端主动发起握⼿请求,将TCP报⽂头部SYN标志位置为1,随机产⽣⼀个序号seq=x,发送第⼀个SYN包给服务器端,客户端从CLOSE状态进⼊SYN_SENT状态,等待server确认。
2次握⼿:server端收到来⾃客户端的数据包后,解析知道了客户端要建⽴TCP连接的请求,server端将TCP报⽂头部标志位SYN和ACK 都置为1,ack=x+1;并且随机产⽣⼀个seq=y,并将数据包发给客户端,server端从LISTEN状态进⼊SYN_RCVD状态。
3次握⼿:客户端收到server端返回的确认后,校验ack=x+1值正确,客户端将标志位ACK置为1,ack=y+1,并把数据包发给server, server端收到ACK包后先校验ack=y+1;如果校验成功,那么成功建⽴TCP连接;ps:三次握⼿的数据包被称为握⼿包,是由操作系统来处理的四次挥⼿:正常断开⼀个TCP连接。
tcp连接是全双⼯通信,所以通信双⽅每⼀个⽅向的接收/发送都需要单独进⾏关闭。
主动断开TCP连接有可能是server端,也有可能是客户端;正常断开连接是由客户端主动发起的1次挥⼿:客户端向server发送⼀个FIN包,将TCP报⽂头部FIN状态位置1,向server发送出FIN包后客户端进⼊FIN_WAIT1;2次挥⼿:server收到来⾃客户端发的FIN包,回复客户端,将TCP报⽂头部ACK状态位置1,server端由ESTABLISHED状态进⼊CLOSE_WAIT状态,这时如果server有数据可以继续正常发送,只是不再接收数据了。