TCP 总结
通信过程
![通信过程](/image/network/tcp 通信过程。png)
服务端:
- socket:建立 socket
- bind:绑定服务端 ip
- listen:开始监听
- accept:等待连接(阻塞)
- read/write:通信
- close:关闭连接
三次握手——建立通信过程
涉及到状态:
- closed
- SYN_SENT
- SYN_RECV
- ESTABLISHED
四次挥手——断开连接
涉及到状态:
- ESTABLISHED
- FIN_WAIT1
- FIN_WAIT2
问题总结
-
tcp 的 2MSL 问题
MSL:Maximum Segment Lifetime,最长报文时间
2MSL 即两倍的 MSL ,TCP 的 TIME_WAIT 状态也称为 2MSL 等待状态,
当 TCP 的一端发起主动关闭,在发出最后一个 ACK 包后,
即第 3 次握手完成后发送了第四次握手的 ACK 包后就进入了 TIME_WAIT 状态,
必须在此状态上停留两倍的 MSL 时间,
等待 2MSL 时间主要目的是怕最后一个 ACK 包对方(server)没收到,
那么对方在超时后将重发第三次挥手的 FIN 包,
主动关闭端接到重发的 FIN 包后可以再发一个 ACK 应答包。
在 TIME_WAIT 状态时两端的端口不能使用,要等到 2MSL 时间结束才可继续使用。
当连接处于 2MSL 等待阶段时任何迟到的报文段都将被丢弃。
不过在实际应用中可以通过设置 SO_REUSEADDR 选项达到不必等待 2MSL 时间结束再使用此端口。
其他总结:
第一,保证客户端发送的最后一个 ACK 报文能够到达服务器,因为这个 ACK 报文可能丢失,站在服务器的角度看来,我已经发送了 FIN+ACK 报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个 2MSL 时间段内收到这个重传的报文,接着给出回应报文,并且会重启 2MSL 计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个 2MSL 时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
-
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在 LISTEN 状态下,收到建立连接请求的 SYN 报文后,把 ACK 和 SYN 放在一个报文里发送给客户端。——一起发
而关闭连接时,服务器收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送 FIN 报文给对方来表示同意现在关闭连接,因此,己方 ACK 和 FIN 一般都会分开发送,从而导致多了一次。——分开发,多一次
-
为什么不能用两次握手进行连接?
3 次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机 S 和 C 之间的通信,假定 C 给 S 发送一个连接请求分组,S 收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S 认为连接已经成功地建立了,可以开始发送数据分组。可是,C 在 S 的应答分组在传输中被丢失的情况下,将不知道 S 是否已准备好,不知道 S 建立什么样的序列号,C 甚至怀疑 S 是否收到自己的连接请求分组。在这种情况下,C 认为连接还未建立成功,将忽略 S 发来的任何数据分 组,只等待连接确认应答分组。而 S 在发出的分组超时后,重复发送同样的分组。这样就形成了死锁
-
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP 还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为 2 小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔 75 秒钟发送一次。若一连发送 10 个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
-
一个 TCP 可以建立多少 http 连接? 多个,established 期间随意
-
浏览器向服务器发出请求,但中间发生丢包,最后服务器返回了 200OK,分析一下
- 请求和响应属于 http 服务
- 丢包和重传属于 TCP
- Http 不关心这个事儿——丢包,即使丢包,也可正常返回 200
- 原文作者:战神西红柿
- 原文链接:https://tomatoares.github.io/posts/network/TCP-%E6%80%BB%E7%BB%93/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。