引言
最近在结合“慕课网”的实战课程《剑指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
两项任务,所以就是三次握手。
总结
写书不易,出错时难免的,每位作者也都应该收到尊重。
但是毕竟作为教授万千学子的教科书,请求学校选择课本时请慎重。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。