C++网络编程之TCP协议
CSDN 2024-10-16 12:37:01 阅读 50
概述
TCP,即传输控制协议,英文全称为Transmission Control Protocol,是互联网协议套件中的核心协议之一。它工作在OSI七层模型的传输层,也工作在TCP/IP四层模型的传输层。TCP协议的主要目的是:在不可靠的网络环境中提供可靠的、面向连接的、基于字节流的传输服务。
TCP协议主要具有以下五个特点。
1、面向连接。TCP在数据传输之前,必须先建立连接。这种连接是通过三次握手过程建立的,确保双方都已准备好进行数据传输。
2、可靠性。TCP通过一系列机制来确保数据的可靠传输,包括:序列号、确认应答、超时重传、流量控制和拥塞控制等。如果数据在传输过程中丢失或出错,TCP会重新发送数据,直到接收方成功接收为止。
3、有序性。TCP保证数据按照发送的顺序到达接收方,即使在网络中数据包的到达顺序可能被打乱。
4、基于字节流。TCP将应用程序发送的数据视为一个无结构的字节流,而不是一系列的消息。TCP负责将字节流分割成适当大小的段,并在接收端重新组合成字节流。
5、全双工通信。TCP连接允许双方同时发送和接收数据,即通信是双向的。
报文格式
TCP的报文包括两个部分:报文头和数据。报文头又分为固定部分和选项部分。报文头固定部分为20个字节,各个字段的含义如下。
1、源端口号:2字节,标识发送方的应用程序端口。
2、目的端口号:2字节,标识接收方的应用程序端口。
3、序列号:4字节,标识从TCP源端向目的端发送的数据字节流的起始字节的序列号。
4、确认号:4字节,只有在ACK标志位为1时才有效,表示下一个期望接收到的字节的序列号。如果确认号为n,则表示接收方已经成功接收到了所有序列号小于n的数据。如果在规定时间内没有收到确认信息,发送方将重新发送报文段,以防止由于网络问题导致的数据丢失。
5、数据偏移:也称为报头长度,占用4位,表示TCP报头长度(以4字节为单位),因为TCP报头可以包含可选的选项部分。
6、保留:6位,必须置0。
7、标志位:6位,每个标志位都有其特定的功能,具体含义如下。
(1)URG:紧急指针有效。
(2)ACK:确认号有效。
(3)PSH:推送数据到接收应用程序。
(4)RST:重置TCP连接。
(5)SYN:在连接建立时同步序列号。
(6)FIN:没有更多数据从应用程序发送。
8、窗口大小:2字节,指定发送方可接收的数据量。
9、校验和:2字节,用于检测数据包中的错误。
10、紧急指针:2字节,只有当URG标志被设置时才有意义,指出紧急数据的最后一个字节相对于序列号的位置。
报文头选项部分包含一些可选的信息,比如:最大报文长度、窗口扩大因子、时间戳等,用于实现除TCP报文段头部指定功能外的扩展功能。报文头选项部分最长为40个字节,因此,TCP报文头最长可达60个字节。
报文头之后便是数据部分,这部分包含了从应用程序来的实际数据。数据的长度可变,并且它的长度加上TCP报文头的长度,应该等于整个TCP报文段的长度。
三次握手
TCP协议通过三次握手的过程来建立一个连接,这一过程确保双方都准备好进行数据交换,并协商了一些必要的参数。三次握手的详细步骤如下。
第一次握手(SYN):客户端向服务器发送一个SYN(同步序列号)报文段,这个报文段中包含了一个初始序列号,这个序列号用于后续的数据传输。同时,SYN标志位置1。报文段格式为:SYN = 1、序列号 = x。
第二次握手(SYN-ACK):服务器接收到客户端的SYN报文段后,如果同意建立连接,就会回应一个SYN-ACK报文段。这个报文段中也包含了一个新的序列号以及对客户端序列号的确认(ACK),确认号是客户端序列号加1。报文段格式为:SYN = 1、ACK = 1、序列号 = y、确认号 = x + 1。
第三次握手(ACK):客户端接收到服务器的SYN-ACK报文段后,会发送一个ACK报文段作为应答。这个ACK报文段的确认号是服务器序列号加1,表明客户端已经收到了服务器的序列号。报文段格式为:ACK = 1、序列号 = x + 1、确认号 = y + 1。
至此,三次握手完成,TCP连接建立成功,双方现在可以开始交换数据了。每个方向上的数据流都使用自己的序列号和确认号来跟踪数据包的状态,这样就可以确保数据按照正确的顺序到达目的地,并且可以检测出丢失或重复的数据包。
为了更加形象地理解TCP协议三次握手的过程,可以参考下面的时序图。
四次挥手
TCP协议的四次挥手是指在TCP连接的终止过程中,所进行的一系列交互。这一过程是为了确保所有已发送的数据都被正确接收,并安全地断开连接。四次挥手的详细步骤如下。
第一次挥手(FIN):发起方(通常是客户端)发送一个FIN(结束)报文段,告诉对方自己已经没有数据要发送了,希望关闭连接。这个报文段包含一个FIN标志位被设置,以及一个序列号。报文段格式为:FIN = 1、序列号 = x。
第二次挥手(ACK):接收方(通常是服务器)接收到FIN报文段后,发送一个ACK报文段作为应答。这个ACK报文段的确认号是发起方序列号加1,表明接收方已经收到了发起方的FIN报文段。报文段格式为:ACK = 1、序列号 = y、确认号 = x + 1。此时,发起方到接收方的方向上已经完成了关闭,接收方仍然可以向发起方发送数据。接收方在发送完所有数据后,才会继续后续的步骤。
第三次挥手(FIN):当接收方也没有数据要发送时,它也会发送一个FIN报文段给发起方,表示自己也完成了数据发送,希望关闭连接。报文段格式为:FIN = 1、ACK = 1、序列号 = z、确认号 = x + 1。
第四次挥手(ACK):发起方接收到接收方的FIN报文段后,发送一个ACK报文段作为应答。这个ACK报文段的确认号是接收方序列号加1,表明发起方已经收到了接收方的FIN报文段。报文段格式为:ACK = 1、序列号 = x + 1、确认号 = z + 1。
至此,连接正式关闭,双方都不再发送数据。需要注意的是,在最后一次挥手之后,发起方和接收方都会进入TIME_WAIT状态和CLOSE_WAIT状态一段时间,以确保所有的数据包都被正确接收,并且没有迟到的数据包。在这段时间过后,连接将完全关闭。通过四次挥手的过程,TCP确保了在断开连接之前所有数据都被正确接收,从而维持了连接的可靠性。
为了更加形象地理解TCP协议四次挥手的过程,可以参考下面的时序图。
数据传输
TCP协议的数据传输过程是一个复杂的机制,它不仅保证了数据的可靠传输,还提供了流量控制、拥塞控制等功能。在三次握手建立连接之后、四次挥手关闭连接之前,TCP会进行数据的双向传输。双向传输过程中涉及到的一些重要机制和概念包括:数据分割与重组、流量控制、拥塞控制、确认应答、重传机制、错误检测等。下面,分别进行介绍。
1、数据分割与重组。当应用程序将数据传递给TCP时,TCP会根据最大报文段长度MSS来决定如何将数据分割成多个TCP报文段。每个报文段都包含一个序列号,该序列号标识了这个报文段中第一个字节在整个数据流中的位置。接收端根据接收到的报文段中的序列号将数据重新组装起来,以确保数据按照发送顺序正确地重组。
2、流量控制。TCP通过滑动窗口机制来进行流量控制,避免发送方发送数据过快导致接收方来不及处理。接收方会在其ACK报文中告诉发送方当前可以接收的最大数据量(即窗口大小),发送方只能发送不超过这个窗口大小的数据。随着接收方处理能力的变化,接收窗口的大小会动态调整,以适应不同的网络状况。
3、拥塞控制。为了防止网络拥塞,TCP实现了一系列的拥塞控制算法,比如:慢启动、拥塞避免、快速重传和快速恢复等。
(1)慢启动。当连接刚刚建立或发生超时重传时,TCP采用慢启动策略,逐渐增加发送速率,直到达到某个阈值或出现丢包。
(2)拥塞避免。一旦进入稳定状态,TCP会使用拥塞避免算法来维持一个相对稳定的发送速率,同时监测网络拥塞情况。
(3)快速重传。如果发送方连续收到相同的ACK,则认为有报文丢失,并立即重传该报文,而不等待超时定时器到期。
(4)快速恢复。在快速重传后,TCP进入快速恢复阶段,继续调整发送速率,直到网络状况恢复正常。
4、确认应答。当接收方正确地接收到一个TCP报文段后,它会发送一个ACK报文段给发送方。这个ACK报文段中包含了确认号,该号码是期望接收的下一个字节的序列号。比如:如果接收方收到了序列号为100到200的数据,那么ACK报文段中的确认号将是201,表示“我已经收到了直到200为止的所有数据,接下来请发送从201开始的数据”。
5、重传机制。TCP为每个报文段设置了一个重传计时器,如果在这个时间内没有收到相应的ACK,就认为报文段丢失并重发。如果发送方收到连续的重复ACK,则可能意味着某个报文段丢失或延迟,此时发送方会提前重传丢失的报文段。
6、错误检测。每个TCP报文段都包含一个校验和字段,用于检测传输过程中可能出现的数据损坏。如果计算出的校验和与接收到的不匹配,报文段会被丢弃,并要求重传。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。