目录
1.Tcp协议介绍
1.1 Tcp协议层级
1.2 TCP协议的格式
2. 确认应答机制
2.1 确认应答
2.2 序号字段
2.3 捎带应答
3. 流量控制
4. 三次握手 四次挥手
4.1 认识标志位
4.2 简单认识
4.3 三次挥手
4.4 四次挥手
1.Tcp协议介绍
1.1 Tcp协议层级
计算机网络:TCP/IP网络协议-CSDN博客
下面是TCP/IP网络协议族层级划分,TCP协议位于传输层。其中传输层和网络层都归属于操作系统层面。
TCP协议全称是传输控制协议(Transmission Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议。顾名思义,Tcp协议要对数据传输进行控制。
- 如下图,用户从主机A发送消息,应用层通常需要对数据进行序列化。序列化是对某个数据结构按照特定格式组织称一条完整数据。而反序列化是将一条数据转按照特定格式转换成原来对应的数据结构。
- 序列化后的数据通过write系统调用拷贝给TCP层中的发送缓冲区,每往下一层,都要加上对应的数据报头。
- 之后,通过网络传输到主机B。先从物理层开始,对数据包进行解包分用。当到主机BTCP层的接收缓冲区,就会得到对方发来的序列化数据。通过read系统调用函数,读取缓冲区的数据,再进行反序列化,主机B的用户就会接受到发来的消息。
TCP协议对应的文件描述符是全双工的,既可以接收数据,也可以发送数据。因为TCP层中有两个缓冲区。数据从TCP的发送缓冲区传输到网络层,会在该数据前面加上TCP协议的报头,下面我们来了解一下TCP协议的格式。
1.2 TCP协议的格式
-
源/目的端口号:这两个端口号分别表示数据是从哪个进程来,到哪个进程去。它们用于识别发送方和接收方的应用程序。
-
32位序号/32位确认号:序号用于标识发送的数据段,确保数据的顺序。确认号用于确认接收到的数据段的序号,确保数据的完整性。
-
4位TCP报头长度:这个字段表示TCP头部有多少个32位(即4字节)。因此,TCP头部的最大长度是15 * 4 = 60字节。
-
6位标志位:这些标志位用于控制TCP连接的状态和传输方式。
- URG:表示紧急指针是否有效。
- ACK:表示确认号是否有效。
- PSH:提示接收端应用程序立即从TCP缓冲区读取数据。
- RST:对方要求重新建立连接,携带RST标识的称为复位报文段。
- SYN:请求建立连接,携带SYN标识的称为同步报文段。
- FIN:通知对方本端要关闭连接,携带FIN标识的称为结束报文段。
-
16位窗口大小:这个字段用于流量控制,表示接收方的缓冲区大小。
-
16位校验和:发送端填充,用于CRC校验。接收端通过校验和来验证数据是否正确。校验和不仅包含TCP首部,还包含TCP数据部分。
-
16位紧急指针:标识哪部分数据是紧急数据。
-
40字节头部选项:这部分暂时忽略。
总的来说,TCP协议的报头长度在20-60字节之间。
2. 确认应答机制
2.1 确认应答
确认应答机制是TCP协议保证可靠性中最重要的一环。
- 主机A向主机B发送一条消息,主机A如何保证消息被主机B接收呢?主机B会向主机A发送确认消息。那么主机B怎么保证这条确认消息被主机A接收呢?主机A也会发送一条确认消息。
- 如此循环下去,你会发现新发的消息永远得不到确认,也就是不可靠。但是历史消息会得到确认,所以说这里的可靠性是指对历史消息的确认。
2.2 序号字段
可是,这么多条历史消息,怎么保证收到的是哪一条消息。TCP将每个字节的数据进行编号,即为序列号。我们可以将tcp的接受缓冲区类比成一个大字符数组,那么每个字节的数据就有了下标,天然就有了编号。
主机A的发送缓冲区拷贝上层的数据,发送出去后,对方接受缓冲区直接一股脑接收到接收缓冲区,本质上就是拷贝数组上的数据。
上图中还是主机A和主机B进行通信。
- 主机A发送的TCP报文中,有序号字段,表示发送数据的顺序。如果主机A报文中序号字段为1000,主机B接受到该条数据,会解析报文中的序号字段。
- 之后,主机B会在组织应答报文时,将TCP报文中确认序号字段填上1001,表示1001序号之前的数据已经获取。即确认序号字段会填写主机收到最大序号数,并加一。
2.3 捎带应答
张三问:“李四今天吃了什么?”。李四回答:“叉烧炒蛋饭。你呢?”。在上面这段对话中,张三向李四发起问答,李四回答后,顺便向张三也发起问答。
tcp通信类似于人类的对答机制。主机A和主机B类比于张三和李四。主机A发送一条消息给主机B,主机B接受到后,组织tcp报文,并填写确认序号字段,同时也携带数据,填写序号字段。
上图中,左边部分才是tcp通信的真实情况。这种机制就是捎带应答。这也是为什么会有确认序号字段的原因。
3. 流量控制
主机A发送大量数据给主机B,主机B的接受缓冲区已经满载了,无法接收新的数据。此时,主机B的操作系统只能丢弃新的tcp报文。不过tcp报文有超时重传机制,超过一定时间没收到确认应答报文,会重发tpc报文。
- 可是这些被丢弃的tcp报文经过无数个路由器,经历千难万险,通过网络发送到目标主机。tcp报文不是需要保证可靠性吗?操作系统不会做浪费时间和空间的事情。
- 主机中的接受缓冲区剩余空间大小决定能接受多少数据,所以只需要知道对方接收缓冲区剩余空间,就可以控制tcp报文携带的数据大小,做到流量控制。
但是任何主机如何知道目标主机的缓冲区剩余空间大小呢?tcp报文中有窗口大小字段,该字段表示本主机接受缓冲区剩余空间的大小。对方主机接受到tcp报文,解析该字段,便知道发送主机的缓冲区剩余空间大小,就可以控制发送的数据大小。
4. 三次握手 四次挥手
4.1 认识标志位
客户端向服务端发送tcp报文,不同的tcp报文通信的功能也不相同,可能是建立连接的请求,正常数据通信请求或者断开连接的请求。
其中ACK表示该报文有确认应答功能,SYN表示向目标主机建立连接,FIN表示要求断开连接。
4.2 简单认识
在确认应答机制中,最新发出的一条消息无法保证是否被接收,但是历史消息能保证被接收,这就是确认应答机制的核心。
三次握手一般是由客户端发起连接请求,服务端收到连接请求后,给予确认应答,并捎带服务端的连接请求,最后客户端进行确认应答。
四次挥手一般是由客户端发起断开连接请求,服务端收到后回复。之后,再由服务端发起断开连接请求,客户端进行确认应答。
4.3 三次挥手
三次握手,本质上双方各自一次请求并接收对方应答,
- 客户端调用connect函数建立连接时,操作系统就会自动组织tcp报文,发起连接请求,此时客户端tcp层处于SYN_SENT。
- 服务端这边需要调用listen函数,处于监听状态,再调用accept函数给新连接分配新文件描述符,让新文件描述符用于客户端通信。此时,操作系统会发送确认应答和连接请求给对方。
- 客户端收到后,便处于ESTABLISHED状态。客户端的操作系统也组织确认应答报文,发送给服务端,服务端接收到之后,也处于ESTABLISHED状态
- 但是客户端发出最后一次的确认应答,是最新一条消息,这是无法保证可靠性,所以说客户端在赌最后一个ACK应答被服务端收到。
为什么要有三次握手?
- 建立双方主机通信意识的共识
- 因为TCP是全双工的,三次握手可以验证全双工通信的通畅性。
4.4 四次挥手
四次挥手中,也是双方的一问一答。
- 先提出断开连接请求的那一方,状态会变成FIN_WAIT_1,接收到对方的断开连接请求的一方,状态会变成CLOSE_WAIT。
- 假设客户端是先提出断开连接的一方,那么接收到断开连接的确认应答后,会变成TIME_WAIT状态。服务端过一会也想断开连接,也会发出断开连接请求。最后都变成CLOSED状态。
- 但是在应用层上,其实是双方调用了close函数,关闭用于tcp通信的文件描述符。而tcp报文的组织和发送都是由操作系统自己完成的。
- 至于为什么会有TIME_WAIT状态,先关闭那一方等待对方关闭连接请求而设置的状态,一般是两分钟。
- 为什么要进行四次挥手呢?因为要关闭两个通信的文件描述符。
不过有些人可能会问,为什么不把中间的断开连接请求和确认断开连接应答合并,使用捎带应答机制,来完成挥手操作。
事实上,TCP协议确实存在通过三次通信完成连接终止的可能性。其关键在于能否实现"FIN-ACK捎带应答"机制——当被动关闭方收到主动关闭方的FIN报文后,如果此时应用层已完成数据处理并立即触发关闭流程,系统可以将ACK确认报文与己方的FIN结束报文合并发送。这种合并使得原本需要四次报文交互的过程(FIN→ACK→FIN→ACK)被优化为三次(FIN→ACK+FIN→ACK)。
但是多数情况下仍然需要完整的四次挥手流程。
最后这是双方正常tcp通信情况。
创作充满挑战,但若我的文章能为你带来一丝启发或帮助,那便是我最大的荣幸。如果你喜欢这篇文章,请不吝点赞、评论和分享,你的支持是我继续创作的最大动力!