共计 1234 个字符,预计需要花费 4 分钟才能阅读完成。
引言
最近在结合“慕课网”的实战课程《剑指 Java
面试 -Offer
直通车》复习基础知识,在复习计算机网络时,发现原来我在书上学的 TCP
相关知识是不准确的,不符合面试要求。
这是我学习计算机网络时使用的课本,让我们一起来见识见识真正的TCP
!
学习
简介
TCP
:全称 Transmission Control Protocol
,传输控制协议。TCP
是面向连接的、可靠的、基于字节流的传输层通信协议。
我们每天都在用的 HTTP
、HTTPS
都是基于运输层的 TCP
协议。
TCP
数据包格式
每个 TCP
报文内都有序号和确认号,结合重传机制保障数据传输的可靠性。
TCP
报文中的下列三种表示十分重要。
ACK
:确认序号标志 SYN
:同步序号,用于建立连接过程FIN
:finish
标志,用于释放连接
三次握手
TCP
连接中最著名的要属 三次握手
了!
详解
第一次握手:建立连接时,客户端发送 SYN (seq = x)
包到服务器,同时进入 SYN_SEND
状态,等待服务器确认。
第二次握手:服务器收到 SYN
包,必须确认客户的 SYN (ack = x + 1)
,同时自己也发送一个SYN (seq = y)
包,即 SYN + ACK
包,此时服务器进入 SYN_RECV
状态。
第三次握手:客户端收到服务器的 SYN + ACK
包,向服务器发送确认包 ACK (ack = y + 1)
,此包发送完毕,客户端和服务器进入ESTABLISHED
状态,完成三次握手。
为什么需要三次握手才能建立起连接?
非常有深度的问题,非认真思考而不可达。
这是《计算机网络》一书中对此的解释。
满满的两页,一句说到核心的都没有。
TCP
三次握手的核心是交换 Client
和Server
初始的Sequence Number
。
假设
我们假设 TCP
连接中没有三次握手。我们再假设通信过程中已经建立好了 Client
到Server
的全双工通信通道。
如果 Client
给Server
发送数据包。该数据包编号是18888
,长度是100
。
如果是正确收到,根据 TCP
的机制,应该回复ACK
,ack = 18988
。
如果是这个数据包时第一个数据包,这样是合理的,回复 18988
,意味着当前的18988
之前的数据包都已经收到了,下一个期待的数据编号是18988
。
假设 Client
和Server
同时发送了两个数据包,18788
和 18888
,而18788
因为网络的问题,传丢了。那服务器端再回复 ACK
就不合理了。
所以,在 TCP
连接中通信的双方,都需要知道对方所开始发送数据的初始的 Sequence Number
。而为了完成这个任务,才有了TCP
的三次握手。
三次握手
- 客户端发送它的
Sequence Number
初始值。 - 服务端确认收到。
- 服务端发送它的
Sequence Number
初始值。 - 客户端确认收到。
2、3
两步可以进行合并,即服务端发一个 TCP
数据包就可以完成确认和发送自己的 Sequence Number
两项任务,所以就是三次握手。
总结
写书不易,出错时难免的,每位作者也都应该收到尊重。
但是毕竟作为教授万千学子的教科书,请求学校选择课本时请慎重。