网络-TCP/UDP详解

本文详细介绍了TCP和UDP协议,包括TCP的头部信息、三次握手和四次挥手过程、拥塞控制算法、滑动窗口机制以及两者的主要区别。此外,还提供了TCP和UDP的客户端与服务端连接代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP释义:

TCP头部信息字段释义:

在这里插入图片描述

源端口号(Source Port)以及目的端口号(Destination Port):

各占2个字节,端口是传输层和应用层的服务接口,用于寻找发送端和接受端的进程,一般来讲,通过端口号和IP地址,可以唯一确定一个TCP连接,在网络编程中,通常被称为一个socket接口。

序号(Sequence Number ,seq):

占四个字节,用来标识从TCP发送端向TCP接收端发送的数据字节流。 因此,如果数据量过大,超过2^32 那么TCP报文就不再发送。

确认序号(Acknowleged Number ,ack):

占四个字节,包含发送确认的一端所期望收到的下一个序号。因此,确认信号应该是上次已经成功收到数据字节 序号+1 。 该字段只在ACK标志被设置时才有效。

数据偏移(Data Offset):

占4bit ,用于指出TCP首部的长度,若不存在此项,则默认为20字节 ,数据偏移的最大值为60字节((2^4-1)*4)。首部长度实际上也指示了数据区在报文段中的起始偏移值。

保留字段:

占6bit,暂时忽略,值全为0。

标志位:6bit。
  • URG(紧急): 为1时表明紧急指针字段有效。用来保证TCP连接不被中断,并且督促中间层尽快处理这些数据。
  • ACK(确认): 为1时表明确认号字段有效。
  • PSH(推送): 为1时接收方应尽快将报文段交给应用层。所谓push操作就是指在数据包到达接收端以后,立即送给应用程序,不再缓冲区进行排队。
  • RST(复位): 为1时表明TCP连接出现故障必须重建连接。用来复位产生错误的连接,也用来拒绝非法错误和非法数据包。
  • SYN(同步): 在连接建立时用来同步序号。
  • FIN(终止): 为1时表明发送端数据发送完毕,请求释放连接。
接收窗口: 目的主机使用两个字节的窗口字段告诉源主机它每次所期望接收到的字节数。

占两个字节,用于流量控制和拥塞控制,表示当前接收缓冲区的大小。在计算机网络中,通常是用接收方的接收能力的大小来控制发送方的数据发送量。TCP连接的一端根据缓冲区的大小来确定自己的接收窗口值,并且将其告诉对方,使对方可以确定发送数据的字节数。

校验和:

占两个字节,范围包括首部和数据两部分。 用于错误检查。源主机基于部分IP头信息,TCP头信息和数据内容计算一个校验和,目的主机也要进行相同的计算,如果收到的内容没有错误过,两个计算应该是完全一样,从而证明数据的有效性。

紧急指针:

占两个字节,指向数据段内的最后一个字节位置,这个字段只在UDP被设置时才有效。

选项:

是可选的,默认情况不选。

填充:

这个字段中加入额外的0,以确保TCP头部是32的整数倍。

TCP网络通信流程:

在这里插入图片描述

TCP三次握手过程:

在这里插入图片描述

第一步:

客户端TCP向服务端TCP发送一个特殊的TCP报文段,不包含应用层数据。但是报文段首部的SYN标志 会被设置为1,表示此报文段为建立连接的报文段,因此为称为SYN报文段 。另外,客户端会选择一个初始序号,记录此报文段的序列号seq=x 。该报文段会封装在一个IP数据报中被发送到服务器端。这个报文段表达的就是希望建立连接的信息。此时,客户端处于SYN-SENT 阶段。

第二步:

一旦包含SYN报文段的IP数据报到达服务器主机,服务器从IP数据报中提取TCP-SYN报文段,为该TCP连接分配需要的缓存和变量,并向客户端发送表示允许连接的报文段。这个报文段也不包含任何应用层数据,但是包含 三个 重要信息:首先,SYN=1 ,其次该报文段确认序号标志ACK=1,确认序号ack=x+1 最后服务器选择自己的初始序号seq=y , 这个报文表达的就是允许建立该连接,自己的初始序号为y,有时也被称为SYNACK报文段。 此时服务器处于SYN-RCVD (RCVD=received=收到)状态。

第三步:

在收到SYNACK 报文段之后,客户端也要给该连接分配缓存和变量,客户端向服务器再发送一个报文段,对允许连接的报文段进行确认。ACK=1,ack=y+1,seq=x+1 。 并且由于连接已经建立,SYN=0 ,并且已经可以携带被传送到服务器的应用层数据 。 服务器接收到第三次握手消息后,处于ESTAB-LISHED状态,处于ESTAB-LISHED状态就可以进行双向通信。

TCP四次挥手过程-断开TCP连接:

在这里插入图片描述

  • 客户端主动发起第一次挥手,FIN=1,seq=u ,客户端发出挥手消息后处于FIN-WAIT-1 状态。
  • 服务端接收到挥手消息后,发起第二次挥手,ACK=1,ack=u+1,seq=v ,服务端处于CLOSE-WAIT 状态。
  • 客户端接收到第二次挥手消息后,处于FIN-WAIT-2状态 ,即客户端不能给服务端发送消息,服务端可以给客户端发送消息(全双工->单向通行)。
  • 服务端发起第三次挥手,FIN=1,ACK=1, seq=w, ack=u+1 ,服务端处于LAST-ACK 状态。
  • 客户端接收到服务端挥手消息,发起第四次挥手,ACK=1,seq=u+1,ack=w+1, 客户端处于TIME-WAIT 状态。
  • 服务端接收到客户端挥手信息,即进入close 状态,客户端再2MSL时间后由TIME-WAIT状态-》CLOSE状态
为什么要等待呢?

为了这种情况:B向A发送FIN=1的释放连接请求,但是这个报文丢失了,A没有接到不会发送确认信息,那么B就会超时重传,这时A在WAIT-TIME 还能够接收到这个请求,这时在回复一个确认就行了。(A收到FIN=1的请求后WAIT-TIME会重新计时)

深入理解:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这个方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
TCP协议的连接是全双工连接 ,一个TCP连接存在双向的读写通道。
简单来说就是先关读,后关写 ,一共需要四个阶段。以客户机发起关闭连接为例:

  • 服务器读通道关闭。
  • 客户机写通道关闭。
  • 客户机读通道关闭。
  • 服务器写通道关闭。
    关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。
详细过程:
第一阶段:客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i;
  1. 服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道
  2. 客户机收到ACK(i+1) 后,关闭客户机写通道
    此时,客户机仍能通过 读通道 读取服务器的数据,服务器仍能通过写通道写数据。
第二阶段:服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j.
  1. 客户机收到FIN(j) 后,返回确认段ACK,序列号为j+1, 在在TIME-WAIT后才能关闭客户机读通道
  2. 服务器收到ACK(j+1)后,关闭服务器写通道
    这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。

从上面可以看到,主动发起关闭连接操作的一方将达到TIME-WAIT 状态,而且这个状态要保持Maximum Segment Lifetime(生存时间)的两倍时间。为什么要这样做,而不是直接进入CLOSED状态?

  1. 保证TCP协议的全双工连接能够可靠关闭。
    如果Client直接ClOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致server没有收到最后回复的ACK,那么server就会在超时后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后server就会收到PST而不是ACK, server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME-WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。
  2. 保证这次连接的重复数据段从网络消失。
    如果Client直接CLOSED,然后又在向server发起一个新连接,我们不能保证这个新连接与刚关闭的连接端口号是不同的。也就是说有可能新连接的端口和老连接的端口是相同的。一般来说,不会发生什么问题。但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达server,由于新连接和老连接的端口号一致,又因为TCP协议判断不同连接的依据是 socket pair(套接字对),于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的连接的数据包发生混淆。所以TCP连接还要再TIME-WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
同时挥手

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况。
在这里插入图片描述

数据可靠性的体现:
  1. 数据通信前进行连接,通信结束后释放连接。
  2. 保证数据完全到达目的端:确认应答机制和超时重传机制。
  3. 接受方接收的数据都是有序的,根据接收的数据头部的序号+数据的大小,就可确定数据的位置以及下一次接收数据的起始位置。
  4. 数据发送和接收是完全相同的,通过头部的校验和字段来判断接收数据是否存在损坏,存在则丢弃,重新接收客户端的发送(超时重传)。

TCP拥塞控制:

一,拥塞控制和流量控制的区别:

流量控制针对的是点对点之间的(发送方和接受方)之间的速度匹配服务,因为接收方的应用程序读取的速度不一定很迅速,而接受方的缓存是有限的,就需要避免发送的速度过快而导致的问题。
拥塞控制是由于网络中的路由和链路传输速度限制,防止过多的数据注入网络中,要避免网络的过载而进行的控制。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程 ,涉及到所有的主机,路由器,以及与降低网络传输性能有关的所有因素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值