【计算机网络】TCP协议

简介: 【计算机网络】TCP协议

TCP协议

TCP的结构

源端口号和目的端口号就是说数据从哪里来到哪里去。

4位首部长度:TCP报头的长度是不固定的报头最短是20字节(没有选项),报头最长是60字节(选项最多是40字节)。

校验和:和UDP协议一样。

保留位:因为UDP的长度是64kb,我们无法改变,所以发明TCP的人做出了改变,加入了保留位,先占个位置,如果后面需要就可以进行扩展使用。

TCP的特点

1.有连接:发送方和接收方会保留对方的信息(如果A和B建立连接,B拒绝了,就无法建立连接,通信就无法完成)

2.可靠传输:A给B发消息,消息有没有成功送达A可以感知到(如果发送失败就可以进行采取一定的措施)

3.面向字节流:TCP的传输和文件操作一样都是以字节为单位的

4.全双工:一个通道允许双向通信就是全双工反之就是半双工(一个socket对象既可以发送数据也能接收数据)

TCP的核心就是可靠传输

TCP如何保证可靠传输

确认应答(可靠机制)

发送方把数据发送给接收方后,接收方收到数据之后就会给发送方返回一个应答报文(acknowledge 简称ack),发送方收到应答报文后就知道自己的数据发送成功了。

每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。

如何确认一个数据包是普通数据还是ack数据呢?

上面的TCP结构图中ACK为1,就表示当前数据包是一个应答报文,此时该数据包中的确认序号字段才能生效,如果这一位为0,则表示当前数据包是一个普通报文,此时该数据包中的确认序号字段不会生效。

通过特殊的ack数据包里携带的确认序号告诉发送方哪些数据已经被收到了,此时发送方就知道自己刚刚发送的数据是否成功。TCP的初心就是可靠传输,达成可靠传输的核心机制是确认应答

超时重传(可靠机制)

A发送数据给B后,可能因为网络拥堵等原因,数据无法到达B;如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。但是,主机A未收到B发来的确认应答,也可能是因为ACK丢失了。

确认应答是一个比较理想的情况,如果网络传输过程中,出现了丢包该怎么办?

首先我们要知道丢包的原因:

如果我们把网络想象成错综复杂的公路,在公路上就会有很多收费站,正常情况如果车流量不大,车辆都能正常通过,但是如果节假日就会发生堵车的情况,这种情况车辆就没办法正常通过。在网络中我们可以把收费站理解成 “路由器/交换机” 如果数据包太多,就会在路由器/交换机中出现 “堵车” 的情况,但是路由器/交换机针对 “堵车” 的情况是比较粗暴的,它会把数据包直接丢掉,此时这个数据包就在网络上消失了。这也就是我们所说的丢包。

丢包是一个随机事件,因此在TCP传输过程中存在两种情况:

无论是哪一种情况,A都会重新传输,如果丢包的概率是10%,再重传一次,两次都丢包的概率就是1%,传输成功的概率是很大的,重传操作大幅度提升了数据传输成功率。

那么发送方何时进行重传呢?

发送方,发出数据后,会等待一段时间,如果这个时间内没有收到ack就会触发重传。

初始的等待时间是可以配置的,也可以动态变化,每经历一次超时重传,下次的等待时间就会变长。但是也不是无限变长,超时重传若干次后就会触发TCP的重置连接。

如果传输的时候ack丢了,触发了超时重传,那么接收方收到了两条一样的数据这样会不会给带来bug呢?

TCP有一个接收缓冲区(一个内存空间)会保留已经收到的数据和数据的序号,接收方如果发现,当前发送方发来的数据是已经在接收缓冲区中,接收方就会直接把这个后来的的数据丢弃掉,以确保读的时候只读到一条数据。

接收缓冲区不仅可以去重,还能进行重新排序,确保发送的顺序。

连接管理(可靠机制)

连接管理:建立连接(TCP三次握手)+ 断开连接(TCP四次挥手)

TCP三次握手:TCP在连接过程中,通信双方一共需要 “打三次招呼” 才能建立连接。

三次握手的核心作用

1.确认当前网络是否通畅

2.让发送方和接收方都知道知道的接收能力和发送能力是否正常

3.让双方在握手过程中针对一些重要的参数进行协商

TCP四次挥手:断开连接(客户端和服务器都可以发起)

TCP四次挥手可以把中间的两次合二为一吗?

不一定

不能合并的原因是ack和第二个fin触发的时机不同,ack是内核响应的(B收到fin会立即返回ack),而第二个fin是应用程序的代码触发的,从服务器收到fin(同时返回ack)再到执行到发起fin的代码,这中间要经历的时间是不确定的。

TCP三次握手的ack和第二个syn都是内核触发的,同一时机,所以可以合并。

滑动窗口(效率机制)

因为TCP的可靠传输会影响传输的效率(多出了一些等待ack的时间,单位时间内能传输的数据就少了),滑动窗口就是让可靠传输对性能的影响少一些。TCP只要引入了可靠性,传输的效率是不可能超过没有可靠性的UDP的。TCP这里的效率机制是为了缩短和UDP之间的差距。

那么TCP是如何提升效率的呢?

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

如果传输过程中出现丢包怎么办呢?

如果通信双方传输的数据量比较小,也不频繁,就任然是普通的确认应答和超时重传,如果通信双方传输的数据量比较大,也比较频繁,此时就会进入滑动窗口模式,按照快速重传的方式处理。

通过滑动窗口的方式传输数据,效率会提升,窗口越大,传输效率越高(一段时间等待的ack多了,总的等待时间就少了)

但是滑动窗口并不是越大越好,如果传输速度太快,接收方就可能会处理不过来,进而接收方就会出现丢包,TCP的前提是可靠传输,在可靠性的基础上再提高传输效率。

流量控制(可靠机制)

接收方处理数据的速度是有限的。如果发送方发的太快导致接收方的缓冲区占满,这个时候如果发送方继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。站在接收方的角度,反向制约发送方的发送速度。(发送方的发送速度不应该超过接收方的处理能力)TCP支持根据接收方的处理能力,来决定发送方的发送速度,这个机制就叫做流量控制

拥塞控制(可靠机制)

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

流量控制是考虑接收方的处理能力,拥塞控制是考虑通信过程中中间节点的情况。

由于中间节点结构复杂难以进行量化,所以我们可以使用 “ 实验” 来找到一个合适的值。

比如,先让A按照比较低的速度先发送数据,如果传输顺利没有丢包,就再尝试更大的窗口大小来发送数据,随着窗口的大小增大,达到一定程度,中间节点可能会出现问题,此时这个节点就可能会出现丢包,,A发现丢包了,就会重新调整窗口大小,如果发现还是丢包,就会继续缩小窗口大小,如果不丢包就尝试增大窗口大小。在这个过程中,发送方不停的调整窗口大小,逐渐达到“动态平衡” 这种做法,相当于是把中间节点都视为“整体” 通过实验的方式找到中间节点的瓶颈。

少量的丢包,我们仅仅是触发超时重传。大量的丢包,我们就认为网络拥塞。当TCP通信开始后,网络吞吐量会逐渐上升。随着网络发生拥堵,吞吐量会立刻下降。拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

延时应答(效率机制)

A把数据传输给B,B就会立即返回ACK给A(正常情况)

A把数据传输给B,B不会立即返回ACK给A(延时应答)

延时应答本质上是为了提升传输效率,发送方的窗口大小就是传输效率的关键,流量控制是根据接收缓冲区的剩余空间来决定发送速度的,如果有办法让流量控制的窗口大小更大,发送速度更快(前提是接收方能处理过来),延时返回ack给接收方更多的时间来读取缓冲区的数据,读取缓冲区的数据之后,缓冲区的剩余空间就更大了,返回的窗口大小就更大了,传输效率就提高了。

比如说,初始情况下,接收缓冲区剩余空间是10kb,如果立即返回ack那么返回的窗口大小是10kb,如果延时一段时间返回ack,在这个过程中读取了2kb,那么此时返回的窗口大小就是12kb。

窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。

捎带应答(效率机制)

捎带应答是在延时应答的基础上又进行了效率提升,在网络通信中往往是 “一问一答”这样的通信模式。

面向字节流

当同时有多个应用层数据包被传输过去的时候就有可能出现粘包问题

那么我们如何解决粘包问题呢?

核心思路:明确应用层数据包之间的边界,①引入分隔符 ②引入长度

异常处理

进程崩溃

进程没了,程序异常终止,文件描述符表也就释放了,相当于是调用了socket.close(),此时会触发FIN,对方收到之后自然就会返回FIN和ACK(正常的四次挥手断开连接)TCP的连接可以独立于进程存在(进程没来,TCP连接不一定断开)

主机关机(正常情况)

进行关机的时候,就会先触发强制终止进程操作(相当于进程崩溃)此时就会触发FIN,对方收到之后自然就会返回FIN和ACK,不仅仅是进程没了,整个系统也可能会关闭,如果在系统关闭之前对端返回的FIN和ACK到了,此时系统还是可以返回ACK的,进行正常的四次挥手,如果系统已经关闭,FIN和ACK没收到,就无法进行后续的ACK响应了,站在对端的角度,对端会以为是自己的FIN丢包了,就会重传FIN,重传几次没有响应就会放弃连接(此时会删除对端的信息)

主机掉电(非正常情况)

主机掉电是一瞬间的事情,来不及杀进程,也来不及发送FIN,主机就直接停机了,对端不一定知道这件事。

①如果对端是在发送数据(接收方掉电),发送的数据就会一直等待ACK,触发超时重传,触发TCP的重置连接功能,会发起 “复位报文段”(TCP结构中的RST)

②如果对端是在接收数据(发送方掉电)对端还在等待数据到达,等了很久没有消息,此时是无法区分对端是没有发送消息还是对方出问题了(挂了)此时接收方也会周期性的给对方发起一个特殊的不携带业务数据的数据包,如果对方没有应答,重复了多次后任然没有响应,此时就会视为对方挂了,就会单方面释放连接。

网线断开

网线断开和主机掉电相似。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
2月前
|
数据采集 算法 数据挖掘
模块化控制协议(MCP)在网络中增强智能体执行效率的研究
随着Web3技术的迅速发展,去中心化应用和智能体在各种领域的应用逐渐增多。MCP(Modularized Control Protocol,模块化控制协议)作为一种增强智能体执行能力的关键技术,为Web3场景中的智能体提供了更强的灵活性和可扩展性。本文将探讨如何利用MCP技术提升智能体在Web3场景中的执行能力,并通过实例代码展示其实现路径。
170 22
|
4月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
130 18
|
5月前
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
163 22
|
5月前
|
网络协议 数据安全/隐私保护 网络架构
|
6月前
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
222 12
|
6月前
|
缓存 网络协议 API
掌握网络通信协议和技术:开发者指南
本文探讨了常见的网络通信协议和技术,如HTTP、SSE、GraphQL、TCP、WebSocket和Socket.IO,分析了它们的功能、优劣势及适用场景。开发者需根据应用需求选择合适的协议,以构建高效、可扩展的应用程序。同时,测试与调试工具(如Apipost)能助力开发者在不同网络环境下优化性能,提升用户体验。掌握这些协议是现代软件开发者的必备技能,对项目成功至关重要。
|
7月前
|
人工智能 自然语言处理 决策智能
智能体竟能自行组建通信网络,还能自创协议提升通信效率
《一种适用于大型语言模型网络的可扩展通信协议》提出创新协议Agora,解决多智能体系统中的“通信三难困境”,即异构性、通用性和成本问题。Agora通过标准协议、结构化数据和自然语言三种通信格式,实现高效协作,支持复杂任务自动化。演示场景显示其在预订服务和天气预报等应用中的优越性能。论文地址:https://arxiv.org/pdf/2410.11905。
199 6
|
9月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
214 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
7月前
|
网络协议 测试技术 Linux
Golang 实现轻量、快速的基于 Reactor 模式的非阻塞 TCP 网络库
gev 是一个基于 epoll 和 kqueue 实现的高性能事件循环库,适用于 Linux 和 macOS(Windows 暂不支持)。它支持多核多线程、动态扩容的 Ring Buffer 读写缓冲区、异步读写和 SO_REUSEPORT 端口重用。gev 使用少量 goroutine,监听连接并处理读写事件。性能测试显示其在不同配置下表现优异。安装命令:`go get -u github.com/Allenxuxu/gev`。
128 0
|
9月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法

热门文章

最新文章