TCP协议的相关特性

目录

TCP(Transmission Control Protocol,传输控制协议)

UDP(User Datagram Protocol,用户数据报协议)

TCP的六个标志位

确认应答

超时重传

连接管理(三次握手,四次挥手)

1.建立连接(三次握手)

2.断开连接(四次挥手) 

TCP状态转换中有几个状态需要了解一下

滑动窗口

 滑动窗口产生的丢包问题

流量控制

拥塞控制

延时应答

捎带应答

面向字节流 

如果解决粘包问题(明确两个包之间的边界)

异常情况


 

首先先了解TCP和UDP协议的特点  

TCP(Transmission Control Protocol,传输控制协议)

  1. 有连接

    • TCP 是一个面向连接的协议,这意味着在两台计算机之间传输数据之前,它们需要首先建立一个连接。这种连接称为 TCP 连接或套接字(socket)。在建立连接后,两台计算机可以通过这个连接来交换数据,直到连接被关闭。
    • 想象你正在给你的朋友打电话。在开始通话之前,你们需要拨对方的号码来建立连接。一旦连接建立,你们就可以开始聊天了。
  2. 可靠传输

    • TCP 提供可靠的数据传输服务。它确保发送的数据包(或称为段)能够完整、准确地到达接收方。
    • 为了实现可靠性,TCP 使用了一系列的机制,如序列号、确认应答、超时重传、流量控制等。
    • 如果数据包在传输过程中丢失或损坏,接收方会向发送方发送一个确认应答(ACK),告知其数据包没有到达或损坏。然后,发送方会重新发送该数据包,直到接收方成功接收到它。
    • 就像你在邮寄信件时,你会确保信件被放入信封并正确贴上邮票,然后放入邮筒。你知道邮局会负责将信件送到收件人的手中,即使信件在途中可能会经过多个邮局。
  3. 面向字节流

    • TCP 将数据视为一个连续的字节流,而不是单独的数据包。当发送方发送数据时,TCP 会将其分割成适当大小的段,并在接收方重新组装这些段以形成原始的字节流。
    • 这意味着 TCP 不保留应用程序发送数据的边界。例如,如果你发送了两个大小为 100 字节的数据包,接收方可能会在一个连续的字节流中一次性读取 200 字节的数据,而不是分别读取两个 100 字节的数据包。
  4. 全双工

    • TCP 支持全双工通信,这意味着两台计算机可以同时发送和接收数据。

UDP(User Datagram Protocol,用户数据报协议)

  • 无连接

    • UDP 是一个无连接的协议,这意味着在发送数据之前,发送方和接收方之间不需要建立连接。每个 UDP 数据包(或称为数据报)都是独立的,可以在任何时间、任何顺序到达接收方。
    • 就像你正在发送一条短信给你的朋友。你不需要先拨对方的号码来建立连接。你只需编写短信并发送即可。
  • 不可靠传输

    • UDP 不提供可靠的数据传输服务。它不保证数据包能够到达接收方,也不保证数据包的顺序或完整性。
    • 如果数据包在传输过程中丢失或损坏,UDP 不会通知发送方,也不会尝试重新发送数据包。
    • 这使得 UDP 更适合对实时性要求较高、但对数据准确性要求不高的应用程序,如视频流、实时游戏等。
  • 面向数据报

    • UDP 将数据视为一个个独立的数据报。每个数据报都有自己的头部信息,包括源地址、目的地址、数据长度等。
    • 这使得 UDP 能够处理来自不同源地址、不同长度的数据报,并将它们分别发送到不同的目的地址。
  • 全双工

    • 同样地,UDP 也支持全双工通信。

TCP的六个标志位

  • SYN(Synchronize):用于建立连接的初始握手。发送方发送一个SYN报文段给接收方,请求建立连接。
  • ACK(Acknowledgement):用于确认数据的传输。当成功接收到数据后,接收方发送一个带有ACK标记的报文段回复发送方,确认已经收到了数据。
  • FIN(Finish):用于关闭连接。当发送方发送完所有数据后,会发送一个带有FIN标记的报文段,请求关闭连接。接收方在收到FIN报文段后,发送一个带有ACK标记的报文段进行确认,并使用一个定时器在一段时间后关闭连接。
  • RST(Reset):用于强制关闭连接。当出现错误或不正常情况时,发送方或接收方可以发送一个带有RST标记的报文段,强制关闭连接,并丢弃已发送或未发送的数据。
  • PSH(Push):用于立即传送数据。发送方可以设置PSH标记,通知接收方尽快将数据传送给应用层,而不是等待缓冲区填满或者等待延迟。
  • URG(Urgent):用于指定紧急数据。发送方可以设置URG标记,表示报文段中有紧急数据需要尽快处理。接收方收到URG标记后,会立即传送该数据给应用层,并进行相应的处理。

确认应答

TCP确认应答是确保可靠性的最核心机制,主要机制就是,发送方在发完数据后,接收方会返回一个应答报文(ACK),表示已经收到数据,其中每个ACK都带有序列号,意思是告诉发送方我已经收到该序列号以前的全部数据,下次发送数据从该数据以后发送.

并且数据在到达接收方后,会先放到数据缓冲区内,为了防止"后发先至"的情况,会按照序列号排序好

超时重传

是确认应答的补充,一切顺利的话就会有应答报文返回有没有收到数据,这里就要分两种情况讨论

  • A--->B发送失败,数据丢包了,A等待特定时间没有收到B返回的ACK就重发数据包给B
  • A--->B发送成功,但B返回的ACK丢了,A还会等待特定时间后,重发数据,这时B的缓冲区中加上之前的就会有多份一样的数据包,这里利用序列号进行数据的去重

这里重传还有需要注意的是,如果重发多次都等不到对应的ACK报文返回,重传的频率就会降低,达到一定次数,TCP就会任务网络或者对端主机出现异常,强制关闭连接

连接管理(三次握手,四次挥手)

1.建立连接(三次握手)

  • 首先客户端向服务器发送syn(连接请求)
  • 服务器接收到syn后,向客户端返回ack,同时服务器向客户端发送syn
  • 客户端收到syn后向服务器返回ack

2.断开连接(四次挥手) 

  1.  客户端向服务器发送一个fin(结束报文)
  2. 服务器接收到fin后,向客户端返回一个ack
  3. 服务器同时向客户端发送一个fin
  4. 客户端接收到fin后向服务器返回一个ack
  • 三次握手,syn和ack一定可以合起来一起发送 ,因为都是内核完成的
  • 四次挥手不一定可以三次完成,因为fin是程序代码控制发送,ack是内核控制,触发时间不一定相同,本身和在一起发送就是为了节省调度消耗,而强制让这两不一定时间的发出的报文放一起,可能得不偿失反而浪费时间
  • 建立连接,一定是客户端主动发起的
  • 断开连接,客户端服务器都有可能发起
  • 建立连接的意义:1.确认当前通信路径是否畅通,2.验证发送和接受能力是否正常,3.通信双方,共同确认一些通信中的必备数据

TCP状态转换中有几个状态需要了解一下

  • TIME-WAIT状态:是TCP主动关闭方在发送FIN和ACK后等待一段时间以确保没有迟到的报文段的状态。
  • CLOSE-WAIT状态:是TCP被动关闭方在收到FIN和发送ACK后等待应用程序关闭连接的状态。如果应用程序没有关闭连接,连接将保持在CLOSE-WAIT状态,可能导致资源耗尽。
  • LISTEN状态:是服务器套接字等待客户端连接请求的状态
  • ESTABLISHED状态:是TCP连接正常数据传输的状态,表示两台机器之间的通信是活跃的。

滑动窗口

左边是因为可靠传输,引起的效率低,引入滑动窗口,可以提升一点效率,如右图

      相比发送一条数据, 收到ACK后发送下一条, 滑动窗口可以一次性发送 N 条数据报,收到 M 条 ACK 的应答后, 窗口向右移动M个位置,并继续发送窗口中没有发送的数据。这样就可以做到将多个 ACK 的等待时间重叠在一起,使用一份时间等待多个ack,总的等待时间缩短了,整体的效率就提升了。批量发送数据:一次发送多条数据,一次等多个ack,称为滑动窗口

  • 窗⼝⼤⼩指的是⽆需等待确认应答⽽可以继续发送数据的最⼤值. 上图的窗⼝⼤⼩就是4000个字节 (四个段).
  • 发送前四个段的时候, 不需要等待任何ACK, 直接发送;
  • 收到第⼀个ACK后, 滑动窗⼝向后移动, 继续发送第五个段的数据; 依次类推;
  • 操作系统内核为了维护这个滑动窗⼝, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只
  • 有确认应答过的数据, 才能从缓冲区删掉;
  • 窗⼝越⼤, 则⽹络的吞吐率就越⾼

 滑动窗口产生的丢包问题

  • ACK丢了:不要紧,不要重传,因为TCP的确认序号的一意义就是表示该序号之前的数据都收到了,比如2001ACK没有返回,只要大于2001的ACK返回了,就表名2001的数据包已经收到但是如果最后一个丢了就照样超时重传
  • 数据包丢了(快速重传升级版):当发送端检测到同一丢失数据包在重复ACK中连续三次被确认(这通常被称为“三重重复ACK”)时,它认为这是一个强烈的指示,表明丢失的数据包已经丢失,并且后续的数据包正在到达接收端。在这种情况下,发送端会假设丢包的可能性很高,并立即重传该丢失的数据包,而不是等待正常的超时期限到期

 

流量控制

因为滑动窗口越大,传输数据也就越快,但是不能无限大,这里流量控制及时接收方的数据处理能力来调整窗口大小,反过来影响发送方的发送速度,

流量控制的核心

  • 接收端将⾃⼰可以接收的缓冲区⼤⼩放⼊ TCP ⾸部中的 "窗⼝⼤⼩" 字段, 通过ACK端通知发送端;
  • 窗⼝⼤⼩字段越⼤, 说明⽹络的吞吐量越⾼;
  • 接收端⼀旦发现⾃⼰的缓冲区快满了, 就会将窗⼝⼤⼩设置成⼀个更⼩的值通知给发送端; 发送端接受到这个窗⼝之后, 就会减慢⾃⼰的发送速度;
  • 如果接收端缓冲区满了, 就会将窗⼝置为0; 这时发送⽅不再发送数据, 但是需要定期发送⼀个窗⼝探 测数据段, 使接收端把窗⼝⼤⼩告诉发送端

接收方接收缓冲区剩余空间0 ---> 窗口大小设置为0 ---> 发送方不会发送数据 

拥塞控制

虽然TCP有了滑动窗口,可以高效的传输大量数据,但是这里如果一开始就发送大量数据仍然可能会引起问题,为解决这一问题,这里TCP引入了慢启动机制,先少量数据传输,检测当前网络拥堵状态,如果正常在指数增长传输的数据量,到达一定慢启动阈值后就开始线性增长,如果丢包了引起超时重发,这里就会调整慢启动阈值,并从新的阈值开始继续线性增长,再不断调整阈值大小,这里线性增长只会出现在一开始

总的来说就是TCP协议想尽快可能把数据传输给对方,但是又要避免给网络造成太大压力的折中方案 

延时应答

一般每个发送出去的数据都会返回一个对应ACK,为了提升效率,此时每个几个数据或每个一段时间再返回一个ACK

数量限制:每隔N个包就应答一次

时间限制:超过最大延迟时间就应答一次

这种操作的优点就是:

  • 有效传输
  • 减少ACK数量,也就是节省开销


 

捎带应答

捎带应答也就是像三次挥手,中间有一个数据和ACK合并发送给发送端,主要是为了节省开销

面向字节流 

当应用程序通过TCP发送数据时,TCP会将数据分割成多个TCP报文段,每个报文段包含一部分数据。这些报文段的长度可能并不相同,取决于多种因素,如网络状况、拥塞情况等。在接收端,TCP会将这些报文段重新组合成原始的字节流,并交付给应用程序

这里就会引出一个粘包问题 

意思就是这里的包是应用层的数据包,站在传输层的角度上,TCP是一个一个报文发过来,按照序号拍好放到缓冲区,在应用层角度上看到的只是一串连续字符串,因为TCP也没有像UDP一样的"报文长度"的字段,多个应用层数据混淆不清了,所以应用程序读取字节数据,就会读多,或者读少的问题,也就是我们所谓的粘包问题

如果解决粘包问题(明确两个包之间的边界)

  • 对于定长的包,也就是确定了每个包都是一样长的,就可以从缓冲区每次读取该长度,依次读取就好
  • 对于变长的包,也就是不确定具体长度的情况下,可以在包头位置约定好包的总长度,也可以在包与包之间使用明确的分隔符(这里程序员自己定就好了,只要分隔符不和正文冲突)

异常情况

  1. 进程崩溃:进程崩溃也就是进程的PCB没有了,也就是文件描述符表被释放了,也就是相当于调用了socket.close(),也就是崩溃的一方先发出FIN进而触发四次挥手,也就相当于进程被正常释放了。
  2. 主机关机(正常关机):正常关机会先尝试干掉所有的进程(强制终止进程)和进程崩溃的处理是一样的。
  3. 主机掉电(拔电源)/网线断开:主机掉电,也就是我们所说的台式机拔电源的情况。

             主机掉电可以分成两种情况:

  • a)接收方掉电:举个例子,B给A发消息,B发完消息,A没有给返回ACK,此时B就会触发超时重传,若重传仍失败就触发复位报文(RST字符为1)尝试重新连接,若重连操作仍失败,B就会单方面释放连接。
  • b)发送方掉电:同样举个例子,A给B发消息,A突然不发消息了,此时的B不知道A是等会就会发消息还是以后一直就不发了,B就会给A发送一个心跳包(也就是窗口探测包)来触发ACK,来判断A是否还在正常工作或者判断网络是否通畅。

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值