ISN:初始序号,可以看做是一个32比特的计数器,每4ms加1,详见RFC 793
TCP连接是全双工的,每个方向都必须单独关闭
出现场景
服务器在客户端建立连接时刚好断电。可以看出客户端进行了重试,但是重试之间的时间间隔第一次是5.81秒,而第二次间隔是24.00秒。
这种超时重试时间间隔对于BSD版的TCP软件实现来讲,是由于500ms的定时器存在。第一次的间隔一般在5.5-6秒任意时刻超时,而第二次一般稳定在24秒。这是由于TCP在500ms以内获得系统控制的瞬间,可能系统会优先处理其它中断,从而第一次计数器减1会发生在0-500ms的任意一个时刻。而每次TCP 500ms定时器被内核调用时都会修正,因而后续稳定
tos 0x10 表示IP数据报内的服务类型,这里的值为DNS的udp查询
连接一方发送复位报文来中途释放连接【正常是发送FIN】
异常释放的一端将返回RST报文段,收到的一方将终止连接,并通知应用层进行复位,接收方并不对RST报文进行确认。
TCP的一端结束发送后,仍然能接收另一端发送的数据。
应用场景
想仅进行一次排序的操作。流程为从客户端读取用户输入的文件,从服务端进行排序,然后客户端接收排序的结果。对于客户端来讲,当文件传输完毕之后不会再发送数据,此时可以直接关闭,而服务端需要先对数据拍完序,再做回应,此时客户端要保持接收数据的能力,这样就适合使用半关闭(服务端通知客户端也可以使用另外1次TCP连接,但是半关闭可以省掉多余1次的连接过程)
连接的一端已经关闭或异常终止,但是另一端确不知道这个情况。
出现场景
客户端和服务端正在正常通信的时候,突然服务器断电了,这个时候客户端并不知道服务器断电,对于这种情况,如果服务器立即恢复电源再立马重启,当客户端在服务器重启之后发送数据时,服务端则回复复位标识,即TCP的标识位R设置为1,客户端收到信息,知晓连接终止
类似场景:客户使用完自己的电脑,直接把电脑电源线拔了,这时服务器并不知道客户端已经消失,后续客户端再开机又会建立新的连接,这样导致服务器会存在许多半打开的连接
通信双方发送的SYN同时到达对方,且一端发送的端口和另一端要求接收的端口一样。
出现场景
主机A应用程序使用本地端口7777,与主机B端口8888执行主动打开,主机B应用程序则使用本地端口8888,与主机A端口7777执行主动打开
报文状态变迁如下
整个过程打开需要4次报文段交换,tcp本身的设计保证,这种场景仅建立了1个连接
其它协议族可能建立两条,比如OSI运输层
通信双方都执行主动关闭。状态变化如下:
交换的报文段和正常的关闭使用的数目一样。
RST发生一般是接收端收到的包很明显和当前连接没有啥关系,这时候就触发RST包产生
上图为客户端CRASH然后客户端重连,下图为客户端CRASH然后服务端向客户端返回数据
此时没有需要发送的东西,队列中也没有未完成的东西需要发送,就生成一个FIN包,发送出去,断开连接
有要发送的东西,比如ack,就去建立连接
MSL(Maximum Segment Lifetime)是报文段的最大生存时间。
生存时间是有限的,由于TCP报文段是以IP数据报在网络内传输,而IP数据报通过TTL的跳数限制,因而报文段被丢弃之前,在网络内生存时间有限
当TCP执行主动关闭并发回最后一个ACK,该连接必须在TIME_WAIT状态内等待2倍的MSL时间。
原因:1:TCP主动关闭端发送的ACK如果丢失了,被动关闭端再次重发FIN,这时候的时间等待能够使得TCP主动关闭端发送最后的ACK不会丢失;2下次新的连接可能会复用同一个端口,如果由于网络延迟,老的数据才到,会与新数据发生混合,等待2MSL可以使得老数据完全消失
在2MSL时间段之内,定义这个连接的插口(客户端IP和端口,服务端IP和端口),不能再被 被动断开方使用
如果服务端的连接突然断开再立马重新启动,服务器的这个端口在2MSL时间内客户端无法连接【这里客户端是被动断开方】;同理如果是客户端自己断开,再立马使用相同的端口,在2MSL时间内去连服务器也是无法成功的【这里服务器是被动断开方】。这种场景客户端可以再随便换一个端口即可,但是服务端的一般应用端口都是固定的,容易造成麻烦
TCP服务器会专门安排一个进程,它永远处于LISTEN状态,用来接收客户端的请求,当请求被接收时,系统中的TCP模块就会创建一个处于ESTABLISHED状态的进程
处于LISTEN状态的进程不能接收数据报文段,处于ESTABLISHED状态进程不能接收SYN报文段
伯克利TCP实现多连接处理规则为:
TCP接收连接是放入连接队列,应用层接收连接是从队列中移除
队列的积压数与服务器能处理的最大连接数没有关系