文章目录
运输连接管理
运输连接三个阶段
建立连接
数据传送
连接释放
建立连接
解决3个问题:
确知对方的存在
协商一些参数(最大窗口、是否使用窗口扩大选项和时间戳选项、服务质量……)
对运输实体资源进行分配(缓存大小、连接表中的项目……)
方式
客户-服务器方式
客户:主动发起建立连接的应用进程
服务器:被动等待连接建立的应用进程
建立连接过程(握手)
三次握手
服务器:
创建传输控制块TCB:tcp连接表、指向发送和接收缓存的指针、指向重传的队列指针、当前的发送和接收序号
close--收听(监听)
close
客户机:创建传输控制块
客户机:发同步数据包(请求报文段):SYN=1(同步标志位),ACK=0(确认号是否有效标志位),seq=x(任意数),无数据,请求报文段(消耗一个序号/序列号/seq)
close--同步以发送状态
close--收听(监听)
收到后
服务器:发同步数据包(确认报文段,ACK=1):SYN=1,ACK=1,seq=y(自己的序列号),ack=x+1(确认号),无数据,消耗一个序号
收到后:close--收听(监听)--同步收到
可拆分成(确认报文段+同步报文段)
客户机:确认服务器的确认(ACK报文段,无数据时,不消耗序号):SYN=0,ACK=1,seq=x+1,ack=y+1,无数据
收到后:同步发送--已建立连接
服务器:
收到后:同步收到--已建立连接
开始通信(seq要看有没有数据)
服务器:确认号:seq=y+1;ack=x+1
客户机:seq=x+1,ack=y+1+1
两次握手是最基本的,因为客户机必须知道服务器是否接收到请求
为什么要三次握手?
防止已经失效的连接请求报文段突然传到服务器,造成错误。
例如:
失效的报文段在网络节点中停滞,
导致延迟,直到连接释放以后的某个时间点才到达服务器,
服务器以为A又发起了连接请求,
发送确认报文段,
如果没有第3次,B以为建立了连接,
就会等待A的数据,造成资源浪费,
如果3次握手的话,
B收不到A的确认,
就知道没有要建立连接
连接释放
四次挥手
都在已建立连接状态
客户机:主动发出连接释放报文段
终止控制位FIN=1,seq=u(客户机已发送的数据的最后一个字节+1),停止发送数据,主动关闭TCP连接
已建立连接--终止等待1,等待服务器的确认
FIN报文段即使不带数据也消耗一个序号。
服务器:发送确认报文段
ACK=1,seq=v(前面发的最后一个字节+1),ack=u+1
已建立连接--进入关闭等待状态
TCP服务器进程通知高层应用进程,释放A到B的连接,TCP半关闭状态,即客户机已经没有数据要发了。
服务器发送数据,客服机仍然要接收
客户机:收到确认后进入终止等待2,等待服务器的连接释放报文段
终止等待1---终止等待2
服务器:发送完全部数据后,发送连接释放报文段,FIN=1,seq=w(关闭等待状态可能还发了一些数据),ack=u+1
关闭等待---最后确认
客户机:接收后,发送确认报文段:ACK=1,ack=w+1,seq=u+1,启动时间等待计时器(2MSL)
终止等待2--时间等待
若ACK报文段未在规定时间内到达
服务器:超时重传FIN报文段,seq=w,ack=u+1,FIN=1
客户机:发送确认,重新启动2MSL计时器
服务器:收到确认,关闭连接
最后确认--close
客户机2MSL后
时间等待--close
四次挥手状态
FIN_WAIT_1:这个状态比较难看到,因为这时不管服务器在干嘛,都会立刻回应确认报文段
FIN_WAIT_2:表示进入半关闭状态,因为他还有ACK要发
CLOSE_WAIT:服务器需要考虑下自己还有没有数据要发送,有继续发送,没有就可以发送FIN给对方,就是给自己一个缓冲时间处理事情,处理完再关闭
TIME_WAIT:如果在FIN_WAIT_1时收到了FIN+ACK就可以跳过FIN_WAIT_2直接进入TIME_WAIT,如果经过了就可以进入close
LAST_ACK:等待确认
CLOSE:连接中断
保活计时器
若建立连接后,服务器每收到客户机的一个数据包就会启动保活计时器,当客户端出现故障,服务器等待时间超过了2个小时,服务器会发一个探测报文段,之后每75s发一个探测报文段,若一连发了10个探测报文段仍然没有客户机响应,就判断为客户机出故障,关闭连接。
总结
3次握手理解
第一次客户机……,状态……
……
第3次握手不占序列号
连接步骤
4次握手挥手理解
连接步骤
为什么握手3次,挥手要4次
因为3次握手可以直接发SYN+ACK,确认报文段跟同步报文段是合一起发的,,所以有3次,
挥手时服务器收到FIN时,可能不能立即关闭连接,所以要先发ACK报文段,如果有数据的话要把数据都传完再发FIN,因为连接释放报文段跟确认报文段分开发,所以有4次
为什么挥手时,不能等到全传完再ACK+FIN?
因为这样客户机没有等到确认,会以为是超时,会进行超时重传
就像点外买时,商家要先确认订单,做好了送到了,再让我拿外卖,而不是等外卖做好了送到了,再确认并让我拿外卖
为什么连接释放时,客户机要有时间等待状态
按道理来说,4个报文发送完毕时可以进入CLOSE,但必须假想网络是不可靠的,最后一次ACK可能丢包。
1、若没有时间等待,客户机马上close,当服务器没收到最后一次ACK,就会重传FIN,FIN无人回应,服务器就无法按照正常步骤CLOSE
2、若没有时间等待,客户机马上close,并有新的进程用相同的端口启动连接,当服务器没收到最后一次ACK,就会重传FIN,会被新的客户机接收到,或者新的客户机的连接请求在服务器等待最后一次ACK时到达服务器,服务器会认为请求码错误,会恢复RET重置连接
- 因此需要有等待状态使得如果接收到了重传FIN可以进行最后一次ACK确认
- 经过时间等待,本连接持续时间内产生的所有报文段都从网络上消失,不会对后续连接造成影响
为什么时间等待计时器要2MSL
- MSL是最长报文段寿命,最长生命周期,保证两个传输方向上尚未接收或者迟到的报文段已经消失,如果立刻重启服务可能会收到上个连接的报文段,造成错误
- 保证最后一个ACK能够到达
为什么不能用两次握手
如果采用两次握手,
若第一次连接请求报文段出现网络延迟,
到了连接释放以后的某个时间点已失效的报文段发到服务器时,
服务器会以为客户机发起连接,
会回复确认报文段并等待,
这样引起服务器资源浪费
如果第3次的话,服务器收到客户机确认,
就知道没有要建立连接
如果已经建立连接,客户端突然出现故障怎么办
还有一个保活计时器,
服务器收到一个客户机的报文段后会重置保活计时器,
当超过2个小时没有收到客户机的回复,
将会发送探测报文段给客户机,
之后每隔75s发送一次探测报文段,
若连续发了10个没有收到客户机的回复,
便认为客户机出现故障,断开连接