TCP协议中的几个核心特性

本文深入剖析TCP协议的关键特性:面向连接、可靠传输与字节流传输。详细解释了TCP与UDP的区别,三次握手与四次挥手的过程,以及滑动窗口、流量控制与拥塞控制等机制。

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

目录

引言

TCP协议

🍑TCP 与 UDP 的 区别

🍑TCP客户端和服务器建立连接的三次握手

 🍑TCP客户端和服务器断开连接的四次挥手

🍑滑动窗口 

🍑流量控制

🍑拥塞控制 

总结


引言

还记得那个经典的图吗?

 今天我们要说的就是其中著名的TCP/IP协议。

TCP协议

🍑TCP 与 UDP 的 区别

有连接与无连接 

有链接:像打电话

需要双方建立连接后才能进行通话

比如说:现在我们要打电话给某个朋友。
输入号码,按下手机拨号键。
手机开始发出 嘟嘟嘟 声音,开始等待对方接听,

而且,我们拨号之后,并不是马上就能接通的!
必须要等待 对方接听之后,我们才能与其交流。

之所以说:有连接 就像 打电话一样,是因为 打电话,必须要接通了之后,才能交流;没有接通,双方就无法交流。
有连接的意思:就是在两者确认建立联系后,就可以开始交互了。

无连接:发微信

不需要接通,直接就能发数据


发微信,我们都知道:发送信息的时候,是不需要对方在线或者回复,按下回车,立马就能加个信息发送出去,不过 对方 看没看见这条消息,我们是不确定的 。
这种情况,就叫做无连接。

TCP,就是要求双发先建立连接,连接好了,才能进行传数据。
而 UDP,直接传输数据,不需要双方建立连接。

 

 可靠传输与不可靠传输

可靠传输:发送方 知道 接收方 有没有接收到数据

🔔注意!不要理解错了。
可靠传输,不是说数据发送之后,对方100% 就能收到。

而是说我数据发送之后,发送方知道对方收没收到我发的消息

比如钉钉在你向别人发送完数据后,如果对方收到了——就会显示已读,如果没收到——就还是未读状态。

🔔这里还有个坑,这里可靠和安全可没有半毛钱关系。

安全,指的是 数据在传输过程,不容易被黑客窃取,不容易被篡改。
可靠,指的是 数据发给对方,发送方能知道接收方有没有收到数据。

 不可靠传输:发送方 不知道 接收方有没有接收到数据

 面向字节流和面向数据报

面向字节流:数据是以字节为单位,进行传输的。

这个就非常类似于 文件操作中的文件内容相关的操作中的字节流。
网络传输也是一样!
假设,现有100个字节的数据。
我们可以一直发完。
也可以 一次发 10个字节,发送十次。
也可以 一次发 2 个字节,发送50次。

面向数据报:以数据报为单位,进行传输

一个数据报都会明确大小。
一次 发送/接收 必须是 一个 完整的数据报。
不能是半个,也不能是一个半,必须是整数个。

在代码中,这两者的区别是非常明显的!

🍑TCP客户端和服务器建立连接的三次握手

 概述:

 

首先客户端主动向服务器发送建立连接的请求——一个SYN同步报文段,服务器收到后就对客户端的请求做出回应,发送ACK确认报文段(表示我收到你的请求了)。同时在服务器发送ACK时候,服务器也会向客户端发送建立连接的请求——SYN(双向奔赴),最后客户端再对我们刚刚服务器发送的建立连接的请求做出回应ACK。

至此,客户端与服务器就成功建立了连接,接下来就可以进行通信了。

那么三次握手具体的意义何在呢?

1、三次握手首先要保证的是当前我们直接的连接是可靠的,接下来我们双方是可以进行相关的通信的 。

就跟我们打电话似的,我们双方在进行通信前,首先要确保我们双方之间的网络是没有问题的——是能够互相听到对方的声音的。

 经过这三次握手,我们互相都知道对方的设备是没有问题的,网络也是没有问题的,我们之间是可以进行正常通信的

2、通过三次握手可以让双方协商一些必要的信息。


三次握手,就让客户端和服务器之间建立好了连接。
其实建立好连接之后,操作系统内核中,就需要使用一定的数据结构来保存连接相关的信息。

 🍑TCP客户端和服务器断开连接的四次挥手

那么如果我们想断开连接,就要经历四次挥手的过程。

与三次握手不同,四次挥手中,既可以是客户端主动断开连接,也可以是服务器主动断开连接。

 看到这里,你可能会觉得这个和上面的三次握手的过程好像呀!那么中间那两个的ACK响应报文段和FIN结束报文端能不能一起发送呢?就像三次握手那样

答案是:中间那两次挥手不一定能够合并!

为啥呢,如下图所示:

 再回头看看三次握手的过程

 总结:

与TCP的连接不同 ,对应TCP连接的断开来说。服务器和客户端任意一方都可以主动断开连接。

比如上面的A想要主动断开连接——A执行了socket.close方法,向B发送了一个FIN(结束报文端),B在收到后操作系统内核马上进行反馈,向A发送了一个ACK(确认报文段)。那么在向A发送ACK的同时,能不能B也给A发送一个FIN(结束报文段)呢?

这样多省事呀!抱歉,还真不一定。我们要明白我们的ACK和之前的SYN都是由操作系统内核进行处理的,所以在之前的三次握手中,内核可以安排ACK和SYN合并一下,一起发送。

但这里呢,我们的FIN(结束报文段)是在用户代码执行了socket.close方法后才会触发的,也就是说FIN什么时候触发是由用户的代码逻辑来决定的——你这里虽然收到了A传来的FIN,但是我们这里的工作还没做完(B这里还没执行到close方法)。那有什么办法,只能等呀!

那么此时B向A发送的ACK确认报文段和FIN结束报文段之间的时间间隔就可能很大——自然就没办法合并到同一个报文段里一起发送。

终于当B中的代码执行到了socket.close方法,向A发送了他的FIN终止报文段。A接收到后,操作系统内核马上做出反馈——对B刚刚发送的报文段进行确认(ACK确认报文段)

至此,A、B之间的连接就算成功的断开了。


🍑滑动窗口 

滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高传输效率!!!

先来看如果不使用滑动窗口,传输是怎样进行的

 如上图所示,我们这样发送一次,收到确认后再发送一次,这样重复的操作是很费时间的。我们把大量的时间都花费在了等待ACK响应上。

于是就有了滑动窗口这样一个机制——一次发送一波数据,然后等待接收方的响应ACK(表示当前接收方已经收到了第xxx个字节的数据,你接着发送就好,窗口就进行了滑动)

上面这段话,你可能不同理解,没关系,接着往下看就好——让我们看看什么是窗口?什么是滑动?

看到这里,想必你已经对滑动窗口这个概念有了一个初步的认识,但是这里还是有些小问题。滑动窗口是提示了发送效率。但是如果出现了丢包该怎么办?

丢包分为两种情况

第一种:ACK丢了

第二种:数据包丢了

 

 总结:

滑动窗口提高发送效率(但可能会影响数据的可靠性)

于是就有了流量控制、拥塞控制来对滑动窗口的发送速率做一个限制(让滑动窗口的大小在一个合理的范围,让他别一次发那么多数据,接收方可以来不及接收,容易造成丢包)

那么具体是怎样来限制呢?

🍑流量控制

对于流量控制——就是根据接收方的处理能力(接收缓冲区剩余空间大小)通过ACK确认报文段来告知发送方当前接收缓冲区中的剩余空间大小是多少,然后发送方就根据这个数据来不断的改变当前滑动窗口的大小。

那么问题来了,这个所谓的接收缓冲区大小是个什么东东?

那么如何让我们的发送方知道当前接收方的接收缓冲区的大小呢?

理论说完了,我我们来看一个例子 

 如上图所示:第一次收到接收方的ACK时候,此时的接收缓冲区的大小还是3000字节,然后随着发送方数据的不断发送,这个值不断的减小。终于当接收发收到了发送方的第4000个字节(下一个要接收的字节是4001的时候,此时接收缓冲区满了,发送方就会暂停发送数据.....就这样通过接收缓冲区来动态的调整发送方滑动窗口的大小。


🍑拥塞控制 

流量控制是站在接收方的角度来控制发送速率的(滑动窗口大小)的, 但是对于整体的网络传输而言,不光有发送方和接收方,还有中间各自转发设备。

既然知道了拥塞控制—— 就是从中间这一系列的转发设备来考虑,进而来限制发送方的发送速率(滑动窗口大小)的,那么他处理的具体流程是什么呢?

中间可是有很多设备的,又多又杂,不好处理呀!

总结:

总结

TCP三大核心特性:

面向连接

可靠传输(通过确认应答、超时重传、流量控制、拥塞控制、延迟捎带应答等机制实现)

字节流传输

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小鱼儿哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值