计算机网络七层模型中,传输层有两个重要的协议:
(1)用户数据报协议UDP (User Datagram Protocol)
(2)传输控制协议TCP (Transmission Control Protocol)
UDP 在传送数据之前不需要先建立连接。远地主机的运输层在收到UDP 报文后,不需要给出任何确认。虽然UDP 不提供可靠交付,但在某些情况下UDP 却是一种最有效的工作方式。
TCP 则提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP 不提供广播或多播服务。由于TCP 要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。
UDP 的主要特点是:
首部手段很简单,只有8 个字节,由四个字段组成,每个字段的长度都是两个字节。
前面已经讲过,每条TCP 连接有两个端点,TCP 连接的端点叫做套接字(socket)或插口。套接字格式如下:
套接宁socket= (IP 地址:端口号’)
每一条TCP 连接唯一地被通信两端的两个端点(即两个套接宇)所确定。即:
TCP 连接= {socket1, socket2} = {(IP1: port1), (IP2: port2)}
3次握手链接
4次握手释放链接
断开连接请求可以由客户端发出,也可以由服务器端发出,在这里我们称A端向B端请求断开连接。
各个状态节点解释如下:
下面为了讨论问题的万便,我们仅考虑A发送数据而B 接收数据并发送确认。因此A 叫做发送方,而B 叫做接收方。
“停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。像上述的这种可靠传输协议常称为自动重传请求ARQ (Automatic Repeat reQuest)。意思是重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组。
滑动窗口协议比较复杂,是TCP 协议的精髓所在。这里先给出连续ARQ 协议最基本的概念,但不涉提到许多细节问题。详细的滑动窗口协议将在后面讨论。
下图表示发送方维持的发送窗口,它的意义是:位于发送窗口内的5 个分组都可连续发送出去,而不需要等待对方的确认。这样,信道利用率就提高了。
连续ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
接收方一般都是采用 累积确认 的方式。这就是说,接收方不必对收到的分组逐个发送确认,而是可以在收到几个分组后,对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都己正确收到了。
累积确认 的优点是容易实现,即使确认丢失也不必重传。但缺点是不能向发送方反映出接收方己经正确收到的所有分组的信息。
例如,如果发送方发送了前5 个分组,而中间的第3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。这就叫做Go-back-N (回退N ),表示需要再退回来重传己发送过的N 个分组。可见当通信线路质量不好时,连续ARQ 协议会带来负面的影响。
TCP 的滑动窗口是以字节为单位的。现假定A 收到了B 发来的确认报文段,其中窗口是20 (字节),而确认号是31 (这表明B 期望收到的下一个序号是31 ,而序号30 为止的数据己经收到了)。根据这两个数据, A 就构造出自己的发送窗口,其位置如图所示。
发送窗口表示:在没有收到B 的确认的情况下, A可以连续把窗口内的数据都发送出去。凡是己经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。
发送窗口后沿的后面部分表示己发送且己收到了确认。这些数据显然不需要再保留了。而发送窗口前沿的前面部分表示不允许发送的,因为接收方都没有为这部分数据保留临时存放的缓存空间。
现在假定A 发送了序号为31 ~ 41 的数据。这时发送窗口位置并未改变,但发送窗口内靠后面有11个字节(灰色小方框表示)表示己发送但未收到确认。而发送窗口内靠前面的9 个字节( 42 ~ 50 )是允许发送但尚未发送的。
再看一下B 的接收窗口。B 的接收窗口大小是20,在接收窗口外面,到30 号为止的数据是已经发送过确认,并且己经交付给主机了。因此在B 可以不再保留这些数据。接收窗口内的序号(31~50)足允许接收的。B 收到了序号为32 和33 的数据,这些数据没有按序到达,因为序号为31 的数据没有收到(也许丢失了,也许滞留在网络中的某处)。 请注意, B 只能对按序收到的数据中的最高序号给出确认,因此B 发送的确认报文段中的确认号仍然是31 (即期望收到的序号)。
现在假定B 收到了序号为31 的数据,并把序号为31~33的数据交付给主机,然后B删除这些数据。接着把接收窗口向前移动3个序号,同时给A 发送确认,其中窗口值仍为20,但确认号是34,这表明B 已经收到了到序号33 为止的数据。我们注意到,B还收到了序号为37, 38 和40 的数据,但这些都没有按序到达,只能先存在接收窗口。A收到B的确认后,就可以把发送窗口向前滑动3个序号,指针P2 不动。可以看出,现在A 的可用窗口增大了,可发送的序号范围是42~53。整个过程如下图:
A 在继续发送完序号42-53的数据后,指针P2向前移动和P3重合。发送窗口内的序号都已用完,但还没有再收到确认。由于A 的发送窗口己满,可用窗口己减小到0,因此必须停止发送。
上面已经讲到, TCP 的发送方在规定的时间内没有收到确认就要重传已发送的报文段。这种重传的概念是很简单的,但重传时间的选择却是TCP 最复杂的问题之一。
TCP采用了一种自适应算法 ,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间RTT,TCP 保留了RTT的一个加权平均往返时间RTTs (这又称为平滑的往返时间, S 表示Smoothed 。因为进行的是加权平均,因此得出的结果更加平滑)。每当第一次测量到RTT样本时, RTTs值就取为所测量到的RTT样本值。但以后每测量到一个新的RTT样本,就按下式重新计算一次RTTs:
新的RTTs = (1 - α)×(旧的RTTs) + α ×(新的RTT样本)
α 越大表示新的RTTs受新的RTT样本的影响越大。推荐的α 值为0125,用这种方法得出的加权平均往返时间RTTs 就比测量出的RTT值更加平滑。
显然,超时计时器设置的超时重传时间RTO (RetransmissionTime-Out)应略大于上面得出的加权平均往返时间RTTs。RFC 2988 建议使用下式计算RTO:
RTO = RTTs + 4 × RTTd
RTTd是RTT 的偏差的加权平均值,它与RTTs和新的RTT样本之差有关。计算公式如下:
新的RTTd= (1- β)×(旧的RTTd) + β × |RTTs-新的RTT样本|
发现问题: 如图所示,发送出一个报文段。设定的重传时间到了,还没有收到确认。于是重
传报文段。经过了一段时间后,收到了确认报文段。现在的问题是:如何判定此确认报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?
若收到的确认是对重传报文段的确认,但却被源主机当成是对原来的报文段的确认,则这样计算出的RTTs 和超时重传时间RTO 就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,则按此方法得出的超时重传时间RTO 就越来越长。
若收到的确认是对原来的报文段的确认,但被当成是对重传报文段的确认,则由此计算出的RTTs 和RTO 都会偏小。这就必然导致报文段过多地重传。这样就有可能使RTO 越来越短。
Kam 提出了一个算法:在计算加权平均RTTs 时,只要报文段重传了就不采用其往返时间样本。这样得出的加权平均RTTs 和RTO 就较准确。
新问题: 设想出现这样的情况:报文段的时延突然增大了很多。因此在原来得出的重传时间内,不会收到确认报文段。于是就重传报文段。但根据Kam 算法,不考虑重传的报文段的往返时间样本。这样,超时重传时间就无法更新。
解决方案: 对Kam 算法进行修正,方法是z报文段每重传一次,就把超时重传时间RTO 增大一些。典型的做法是取新的重传时间为2 倍的旧的重传时间。当不再发生报文段的重传时,才根据上面给出的公式计算超时重传时间。
流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收。
利用滑动窗口机制可以很方便地在TCP 连接上实现对发送方的流量控制。
接收方的主机B 进行了三次流量控制。第一次把窗口减小到rwnd =300,第二次又减到rwnd = 100 ,最后减到rwnd = 0 ,即不允许发送方再发送数据了。这种使发送方暂停发送的状态将持续到主机B 重新发出一个新的窗口值为止。我们还应注意到,B 向A 发送的三个报文段都设置了ACK=1,只有在ACK=1 时确认号字段才有意义。
发生死锁: 现在我们考虑一种情况。上图中, B 向A 发送了零窗口的报文段后不久, B 的接收缓存又有了一些存储空间。于是B 向A 发送了rwnd = 400 的报文段。然而这个报文段在传送过程中丢失了。A 一直等待收到B 发送的非零窗口的通知,而B 也一直等待A 发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。
解决方案: TCP 为每一个连接设有一个 持续计时器(persistence timer) 。只要TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个 零窗口探测报文段 (仅携带1 宇节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。
1 TCP连接时是三次握手,那么两次握手可行吗?
在《计算机网络》中是这样解释的:已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ACK包。这样就会白白浪费资源。而经过三次握手,客户端和服务器都有应有答,这样可以确保TCP正确连接。
2 为什么TCP连接是三次,挥手确是四次?
在TCP连接中,服务器端的SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中,B端向A端发送的ACK和FIN是是分两次发送的。因为在B端接收到A端的FIN后,B端可能还有数据要传输,所以先发送ACK,等B端处理完自己的事情后就可以发送FIN断开连接了。
3 为什么在第四次挥手后会有2个MSL的延时?
MSL是Maximum Segment Lifetime,最大报文段生存时间,2个MSL是报文段发送和接收的最长时间。假定网络不可靠,那么第四次发送的ACK可能丢失,即B端无法收到这个ACK,如果B端收不到这个确认ACK,B端会定时向A端重复发送FIN,直到B端收到A的确认ACK。所以这个2MSL就是用来处理这个可能丢失的ACK的。
1 文件传送协议
文件传送协议FTP (File Transfer Protocol) [RFC 959]是因特网上使用得最广泛的文件传送协议,底层采用TCP协议。
盯P 使用客户服务器方式。一个FTP 服务器进程可同时为多个客户进程提供服务。FTP的服务器进程由两大部分组成:一个主进程,负责接受新的请求:另外有若干个从属进程,负责处理单个请求。
在进行文件传输时,客户和服务器之间要建立两个并行的TCP 连接:“控制连接”(21端口)和“数据连接”(22端口)。控制连接在整个会话期间一直保持打开, FTP 客户所发出的传送请求,通过控制连接发送给服务器端的控制进程,但控制连接并不用来传送文件。实际用于传输文件的是“数据连接”。服务器端的控制进程在接收到FTP 客户发送来的文件传输请求后就创建“数据传送进程”和“数据连接”,用来连接客户端和服务器端的数据传送进程。
2 简单文件传送协议TFTP
TCP/IP 协议族中还有一个简单文件传送协议TFfP (Trivial File Transfer Protocol),它是一个很小且易于实现的文件传送协议,端口号69。
TFfP 也使用客户服务器方式,但它使用UDP 数据报,因此TFfP 需要有自己的差错改正措施。TFfP 只支持文件传输而不支持交耳。
3 TELNET
TELNET 是一个简单的远程终端协议,底层采用TCP协议。TELNET 也使用客户服务器方式。在本地系统运行TELNET 客户进程,而在远地主机则运行TELNET 服务器进程,占用端口23。
4 邮件传输协议
一个电子邮件系统应具如图所示的三个主要组成构件,这就是用户代理、邮件服务器,以及邮件发送协议(如SMTP )和邮件读取协议(如POP3), POP3 是邮局协议(Post Office Protocol)的版本3 。
SMTP 和POP3 (或IMAP )都是在TCP 连接的上面传送邮件,使用TCP 的目的是为了使邮件的传送成为可靠的。
(20200807)
TCP被称为面向连接的(connection-oriented),这是因为一个进程可以向另一个进程发送数据之前,两个进程需要先握手,即他们开始互相发送预备报文段,以确保建立数据连接的参数。
TCP是逻辑连接,其共同状态仅保存在两个通信端系统的TCP程序中。而端系统之间的网络元素不会维持TCP的连接状态。中间路由器对TCP完全视而不见,他们只看到数据报,而非连接。
通信特点
全双工(full-duplex service),处在不同主机的进程A和进程B之间存在一条连接,数据可以同时从A流向B和从B流向A。
点对点(point-to-point),在单个发送方和单个接收方之间的连接。
服务器进程和客户进程
发起连接的进程称为客户进程,另一个称为服务器进程。
(20200808)
数据一旦被送进socket,就由客户TCP控制了,TCP将数据放在一个数据缓存(send buffer)里(C/S两端都有),该缓存也是三次握手时数据存放处。TCP会从缓存中取出一块数据,传递给网络层。
TCP首部+客户数据=TCP报文段(TCP segment)
TCP从send buffer中取出并放入报文段中数据的数据量受限于 最大报文段长度(maximum segment size, MSS) ,其根据最初确定的由本地主机发送的最大链路层帧长度(即最大传输单元Maximum transmission unit, MTU)来设置。以太网和PPP链路都有1500字节的MTU,考虑到TCP/IP首部一般是40字节(TCP首部20字节),TCP报文段中数据长度典型值是1460字节。注意到这里的MSS指的是TCP报文段中来自应用层的数据的最大长度。
TCP连接的组成
一台主机上的缓存、变量和连接进程的socket,以及另一台主机上的缓存、变量、socket。
首部+数据字段。当TCP发送一个大文件,比如,TCP通常将该文件划分成长度为MSS的若干,除最后一块,其他的都是MSS长度。而Telnet这样的应用,数据字段只有一个字节长,也就是其TCP一般只有21个字节的长度。
典型长度:20字节/160bits (选项字段为空时)
源端口号:16bits
目的端口号:16bits
序号(seq num):32bits
确认号(acknowledgment num):32bits
接收窗口(receive window field):16bits ,用于流量控制,指示接收方愿意接收的字节数量
首部长度(header length field):4bits ,以32bits的字为长度的TCP首部长度
选项字段(options):可选和变长
标志字段(flag field):6bits ,ACK/RST/SYN/FIN/PSH/URG
序号建立在传送的字节流之上而非报文段的序列值上,the sequence number for a segment是报文段首字节的字节流编号。比如一个待发送的文件共10,000个字节,每个TCP的报文段发送1,000个,则第一个报文段的序号是0,第二个序号是1,000,以此类推。该序号是字节的编号,并用于给报文段编号。
上面的例子中假设初始序号是0,在实际应用中收发两方随机选择初始序号。
确认号略复杂。主机A和B之间建立TCP通信, 主机A填充进报文段的确认号是A期望从B收到的下一个字节的序号 。
报文段的样本RTT(SampleRTT)是报文段被发出(交给IP)到对该报文段的确认被收到之间的时间量。仅为一个已经发送的但目前尚未被确认的报文段估计SRTT,从而产生一个接近每个RTT的新SRTT值;不为已经被重传的报文段计算SRTT;仅为传输一次的报文段测量SRTT。
由于网络环境变化,比如路由器的拥塞和端负载的变化,SRTT并不都是典型的。TCP会维持一个SRTT的均值(EstimatedRTT),并根据下面公式计算ERTT
其中的推荐值 。该指数加权移动平均值(Exponential Weighted Moving Average, EWMA)赋予最近样本的权值要高于旧样本的权值,因越近的样本能更好的反应网络的拥塞状态。
此外,RTT的标准差DevRTT用于估算SRTT偏离ERTT的程度:
推荐值 。
超时间隔应该大于等于ERTT,否则造成不必要的重传。但也不该比ERTT大很多,导致数据传输时延大。当SRTT波动大时,间隔大些,波动小时,间隔小些。
初始推荐值 ,当出现超时候翻倍。只要收到报文就更新ERTT,并根据公式重算TimeoutInterval。
(20200809 Sat)
定时器
定时器的管理需要相当大的开销,因此[RFC 6298]推荐仅使用单一的重传定时器,即便有多个已发送但未被确认的报文段。
(20200809 Sat)
TCP中发送方相关的三个主要动作
发送方对这些主要动作的反馈参考可靠数据传输的部分。
超时间隔的选取
每当超时事件发生,TCP重传具有最小序号的未被确认的报文段。只是每次TCP重传是都会将下一次的超时间隔设为先前值的两倍,而不是用从EstimatedRTT和DevRTT推算的值。然而每当定时器遇到另外两个事件,即ACK和上层数据,定时器的启动TimeoutInterval由最近的ERTT和DRTT推算得到。
TCP两侧的主机都有接收缓存。流量控制服务用于消除sndr使rcvr缓存溢出的可能性。fcs因此是一个速度匹配服务,即sndr的发送速率和rcvr应用程序的读取速率相匹配。
TCP让sndr维护一个接收窗口(receive window)的变量来提供流量控制,即rw用于给sndr一个指示-该sndr还有多少可用的缓存空间。TCP是全双工通信,两端的发送方都维护一个rw。分析一种情况,主机A通过TCP向B发送一个大文件,B为该连接分配一个接收缓存,用RcvBuffer来表示。B的应用进程从该缓存中读取数据。有如下变量
缓存不许溢出,故有 接收窗口用rwnd表示,缓存可用空间数量(即空闲的空间数量)表示为
主机A需要跟踪另外两个变量,LastByteSent和LastByteAcked,对A来说有
一个特例,当B的接收缓存满,rwnd=0,假设此时B没有任何数据要发送给A。考虑到TCP并不向A发送带有rwnd的新报文段, 而事实上TCP仅当有数据或去人要发时才会发送报文段给A。导致A不知道B的接收缓存有新空间,A被阻塞不能在发送数据。解决方案,TCP规范要求,B的接收窗口为0时,A继续发送只有一个字节数据的报文段,这些报文段将会被接收方确认,最终缓存开始清空,且确认报文段将包含一个非0的rwnd值。
(20200805)
TCP建立过程中三个握手(three-way handshake)的作用
三次发送,sndr/rcvr双方各自确认了自身和对方的接收能力和发送能力。握手完成便可建立连接。
(20200807)
前两次握手的报文段不承载"有效载荷",也就是不包含应用层数据,第三个握手可以承载应用层数据。
(20200809 Sat)
完成这三步,C-S可通信,以后每一个报文段的SYN都设置为0。
结束连接
客户打算结束连接,发出一个特殊的报文段,设置其中的FIN=1。服务器接收到回复一个确认报文段,其中的FIN=1。服务器再次发送一个结束连接报文段,FIN=1。客户收到后发送ACK并释放占用的资源。
IP层不会向两个端系统提供有关网络拥塞的反馈信息。略。
发送方sndr设定一个变量,拥塞窗口congestion windown,cwnd,它对TCP发送方能向网络中发送流量的速率进行了限制,并且和前面提到的接收窗口rwnd联合决定了发送速率,即
TCP如何感知它和目的地之间的拥塞
定义丢包事件:出现超时,或者受到来自接收方的3个冗余ACK。
一个丢失的报文段意味着拥塞,当报文丢失应该降低TCP sndr的发送速率。 即减小cwnd。
一个确认报文段指示该网络正在向rcvr交付sndr的报文段,因此,当对先前未确认报文段的确认到达时,能够增加发送方的速率。
贷款检测。
该算法分为三部分,1)慢启动,2)拥塞避免,3)快速恢复。其中的1和2是TCP强制部分。在收到ACK时,慢启动比拥塞避免更快的增加cwnd的长度。
当一个TCP连接开始时,cwnd的值通常设为一个MSS的较小值。这使得发送速率大约为MSS/RTT。如MSS=500Bytes,RTT=200ms,则初始发送速率是20kbps。注意到此时带宽可能比初始速率快的多。慢启动(slow-start)状态,cwnd的值以一个MSS开始并且每当传输的报文段首次被确认就增加一个MSS。这一过程使得每过一个RTT,发送速率就翻番。初始速度慢,但ss阶段以指数增长。
结束ss的情况
TCP重传机制主要是为了防止网路包丢弃,重传的工作方式主要借助TCP头部中的序列号和确认号来决定是否重传,重传的触发方式主要由以下几种:
什么是超时重传?
发送方在发送数据时设置一个定时器,当超过指定时间后如果还没有收到接收方的ACK响应,就会重发数据包。
超时重传的发生场景
什么是RTT?什么是RTO?
RTT就是数据包的往返时间,RTO就是超时重传时间。
RTO的长短对数据包的重传有什么影响?
RTO如何设置?
RTO既不能过长也不能过短,略微大于RTT是最好的。但RTT会因为网络的变化而发生变化,所以在Linux系统中为了计算RTO,会对RTT进行两个采样:
RFC6289建议使用以下公式计算RTO:
上述表达式中,在linux中α = 0125,β = 025,μ = 1,δ = 4,至于为啥是这些值,别问问就是前人大量的测试积累得出。
假设因为网络阻塞触发了超时,如何避免频繁重发加剧网络阻塞?
超时时间加倍,就是每当重传的时候,都会将下一次的超时时间设置为当前值的两倍,避免频繁重发导致网络更加阻塞。
超时重传的弊端是什么?
超时周期可能相对较长,重传的等待时间可能过长。
什么是快速重传?
快速重传不再以时间作为重传的标准,而是以数据作为重传的标准。
上述Seq2因为某些原因没有抵达接收方,但接收方已经收到了Seq3、4、5的数据包,并且回复了三次ACK2的数据包。发送端在收到三次ACK2的数据包以后,就会在超时定时器之前重传Seq2的数据包。
重传所有包还是重传丢失的包?
由于发送端并不知道三次ACK2的数据包是由发送方的哪几个数据包响应回来的(也就是Seq3、4、5),因此只重传Seq2还是要重传所有的数据包也是个问题。
根据TCP实现的不同,上述两种情况都可能存在。
SACK重传
SACK重传其实就是选择性重传,它是为了解决快速重传不知道需要重传哪些包的问题。
SACK是如何让发送方知道重传哪些包的?
TCP的选项字段增加一个SACK字段,接收方会将已经收到数据包序列号范围发送给发送方,这样发送方通过SACK信息就能找到丢失的数据包重传此数据包。
SACK的使用条件
SACK必须要发送方和接收方同时支持,在linux中可以通过netipv4tcp_sack参数开启(Linux24以后默认开启)。
SACK可以让发送方准确的知道哪些数据包接收方没有收到,而D-SACK可以让发送方知道有哪些数据包被重复接收了。
D-SACK的优点是什么?
D-SACK如何让发送方知道ACK包丢失
上图中接收方收到了3000~3999的数据包,但回应的ACK发生了丢失,假设此时触发了超时重传,发送方会首先重传3000~3499的数据包,接收方在收到该包以后发现该包已经被接收过了,于是会回复一个SACK = 3000~3500告诉发送方该数据包已经被接受过了,因为ACK已经到4000了,所以这里是一个D-SACK。发送方在收到报文以后可以知道数据包没有丢,丢的只是ACK报文。
D-SACK如何判断数据包发送延时
上图中1000~1499的数据包被网络延迟,后续发送方收到了三个连续ACK 1000的报文触发了超时重传,重传以后,延时的网络包也抵达了接收方,此时接收方会回复一个SACK=1000~1500,因为ACK已经到了3000,所以这里是一个D-SACK,表示收到了重复的包。发送方收到了该ACK报文以后也可以判断出快速重传的原因是因为网络延迟。
如何开启D-SACK
在Linux下可以通过netipv4tcp_dsack参数开启/关闭这个功能(Linux 24后默认打开)。
以上就是关于计算机网络——TCP/UDP协议全部的内容,包括:计算机网络——TCP/UDP协议、传输层Transport layer TCP, since 2020-08-05、一文带你搞定TCP重传等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)