TCP/IP网络协议介绍及原理分析

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: TCP/IP网络协议介绍及原理分析

一.应用层协议

对于应用层而言,协议是开发者自己进行定义的,开发者根据自定义的格式规范对数据进行编码和解析。

但是从原理上进行分析,其核心主要包括两点内容:

①确定客户端和服务端交互的内容(协议的内容)

②确定传输数据的组织方式

我们使用当下主流的应用层协议进行举例说明:

①HTTP协议

类似于百度的网址,前域名中会包括http的固定格式

https://www.baidu.com/?tn=44004473_52_oem_dg

②XML

d826755e879cb3e707811d5ab66acfab.png

我们通过观察xml的文件格式,我们可以发现:其可读性较高,但是我们在传输数据时,其内容中伴随的各种数据头,在网络传输过程中比较复杂,数据在网络传输过程相对比较冗余,效率较低

③JSON

b0b9c4bcb7cf0ceae3b4a7ce1ad26e32.png


JSON相对于xml对数据头信息做了一定的优化,其相对xml文件内容更美观,可读性高,扩展性也相对较高,数据头信息简化很多,传输效率也较高。

④其他协议

Google:protobuf协议

IBM:MQTT协议,消息队列遥测传输,针对物联网设计的协议:消息以字节的格式传输,不同字节大小的消息代表着不同的含义,省略了多余的字符,大量减少了报文的长度,大幅减少了网络传输中宽带的长度,但是编码和解析的过程相对比较复杂。

传输层协议:由操作系统实现并给上面的应用层提供API接口

二.UDP协议

我们将从UDP协议的几个特点对其进行讲述:

①无连接

按照UDP协议进行数据的传输,只要直到目的ip和端口,就能进行数据的传输。就类似于发短信的过程我们在发短信时,不需要事先与对方进行连接

②不可靠传输

类似于我们发短信的过程,我们负责发短信,并不负责短信是否被接收方收到,也不对数据的正确性进行校验,如果数据错误UDP协议层也不会给应用层返回任何错误信息

③以数据报形式进行数据的传输

用层传输给UDP多大的报文,UDP就必须按照多大的报文进行完整传输,不能对报文内容进行分批循环传输

④大小受限

UDP首部有一个16位的最大长度限制,也就是说,一次UDP传输,只能传输64kb的数据(包含UDP首部)

⑤缓冲区

UDP没有发送缓存区,只有接收缓存区

发送的数据会直接交给内核,然后由内核传输给网络层进行下一步的数据传输。

虽然UDP有接受数据的缓存区,但是缓存区有一定的范围大小,一旦缓存区满了,再发送的数据将会被丢失;同时,缓存区无法保证发送的UDP报和接收到的UDP报一致。

UDP的socket既可以发送数据,也能接收数据,这个概念叫做双全工。

UDP协议的格式:

2ec2f7f3bb691b89d7fc1c8306d143cb.png

0f9dbd0eea8d962cdfc8e1279ef67317.png

65535个字节长度的数据也就是

b7cfa395afdc03e99b63adff7dd4eba3.png


所以UDP每次最多传输64kb的数据

我们对16位UDP检验和进行一定的说明:

数据被转化为字节之后会按照自己的方式进行相加,在数据发出时将结果进行保存,在接收端时数据会重新按照同样的方式进行相加,如果两次校验和数据相同,那么数据是正确的,如果两次校验和不相同,那么说明数据在传输过程中被篡改了,这种数据校验的方式是CRC循环冗余校验

1d583b985f822c675ac7207b25ee7a13.png

三.TCP协议

c68abbc36bde8e00bf943d89fa2f2f88.png

3.1TCP的可靠传输

①确认应答

我们思考这样一个场景:当我们进行聊天时,我们通过对方的回应来确定对方收到了我们发送的消息

3759f0a74bda572d2eed11a700a56bfa.png

如果是在一问一答的情境下,这种回应并不会产生问题,但是如果是在网络乱序的情况下,我们发送了两条消息,对方回应了我们两条消息,我们如何区分对方的回应是针对那条消息的呢?

其实有一个相对简单的方法,对请求和回应都加上序号:

abbbb406cb286cd2a76ac27a939fc596.png

那么在网络传输中,TCP又是如何保证大量数据的正确传输呢?

48bce0b4c027531c5e9b3b7c1defb62b.png

TCP是按照字节流的方式进行数据的传输,也就是说,任何数据在网络传输过程中都会被转化为字节,TCP通过给每个字节添加序列号来达到多条数据的正确传输,具体如下:

9d6f1547090af44868fe229bad2944f7.png

比如在第一次传输过程中,请求方发送了1-1000序号的字节流(在请求时,将SYN设置为1,将请求的数据以字节编号的形式存入32位序号中),然后接收方就返回1001的序号,用来提示请求方下次数据的发送从序号为1001的字节开始,如此反复,直至通信结束。

而这些标识数据的方式,就保存在32位序号和确认序号中。

c6d98d6d9c2ae61a5c0c1760499c8847.png

②超时重传


数据在网络传输过程中会经过很多的网络设备,但是网络设备的储存容量都是一定的,一旦某台网络设备超过了其能储存数据容量的极限,就会将新接收的数据进行丢弃,而对于数据接收方而言,在一定时间内没有接收到请求的数据,我们称之为数据传输超时。


数据传输超时主要包括以下情况:

ceca8b2ba8be74559fc57c5250e46574.png

68f43c2c80dd37e15c6a36d41ec51f91.pngTCP超时重传机制就是为了解决数据丢失问题:对于数据的发送方而言,如果发送了数据,在请求时间内没有接收到回应,就会重新再发送一遍数据,但是对于接收方而言,如果是因为在发送回应数据时出现了丢包问题,那么其接收数据是不是就重复了呢?


事实并非如此,对于数据接收方而言,其存在一个数据缓存区(我们可以将其理解为一个阻塞队列),数据放入时我们首先会检查缓存区中是否存在这些数据,如果存在就将新数据丢弃,不存在则加入,这样就保证了socket api拿到的为不重复的数据。


那么超时时间又该如何确定呢?

6d8a46868603a2bd7d383cb5bd490342.png

③连接管理

目的:在发送方和请求方初次建立连接的时候,保证双方具有收发数据的能力,换句话说,要通过连接管理来确保网络数据传输的稳定性和有效性

①三次握手

6271d77efe0c19306fcfc353a3f9a120.png

5658900d621650a3cc69bf006f204604.png

三次握手的过程可以这样理解:发送方发送数据给接收方,接收方受到数据给出回应,同时接收方也主动发送数据给发送方,最后发送方回应接收方的请求(我们通常把接收方的第一次的回应主动发送请求理解为一次数据传输,所以称为三次握手)


三次握手的目的是为了检测网络进行数据传输的可靠性,如果三次握手没有满足,那么双方需要重新协商一些其他信息。

ab106ae60672a5e42b75f812812cdc90.png

当发送方给接收方发送数据时,syn置为1,当接收方发送回应给发送方时,ack置为1,当两者同时置为1时我们称之为同步请求

在三次握手时状态的变化:

440d60cbc7a383a79db6db66d875439a.png

总结:

5182674f72aa6f89d317104141e1baaa.png

②四次挥手

保证发送方和接收方进行有效的断开连接


705f159a5ee2170fbdad2110048688c3.png

发送方发起断开连接请求,接收方回应请求,同时接收方也发起断开请求,最后发送方给出ACK回应

b9ae7923aab11061323cfa8f49126d91.png

四次挥手服务端状态分析:


CLOSE_WAIT:四次挥手挥了了两次之后出现的状态,这个状态就是在等待代码中调用socket.close()方法来进行后续的挥手过程~正常情况下,一个服务器上不应该存在大量的CLOSE_WAIT。如果存在,说明大概率是代码存在bug,close没有被执行到


TIME_WAIT:谁主动发起FIN,谁就进入TIME_WAIT.起到的效果就是给最后一次ACK提供重传机会,表面上看起来A发送完ACK之后就没有A的事了,按理说A此时就应该销毁连接释放资源了,但是并没有直接释放,而是会进入TIME_WAIT状态等待一段时间,一段时间之后再进行释放,目的是,怕最后一个ACK丢包,如果最后一个ACK丢包了就意味着B会重传FIN,这时则需要发起者重新回应ACK


总结:

bc7dfd11b820a02d87739f36dd3ed3a5.png

TIME_WAIT应该持续多久:2*MSL


为什么呢?


TIME_WAIT状态是为了防止最后一个ACK在传输过程中的丢包问题,正常接收端接收到ACK的时间是MSL,但是由于在这个时间内没有收到ACK,那么接收端则重新发起FIN请求,这时FIN传输到发送端也需要FIN的时间,所以为了避免ACK的丢包问题,TIME_WAIT时间应该存在2*MSL


四.TCP协议实现功能的完善


①滑动窗口


在数据传输过程中,正常我们所理解的是请求方传输一条数据,并从响应方获取响应,在等待响应的过程中,我们无法去执行有关该条数据有关的任务,但在真实的网络环境中数据是进行批量发送和批量响应的。


为了提高网络传输的效率(实现数据的批量请求和响应),滑动窗口这一数据结构应运而生。


通过滑动窗口,我们一次可以传输很多组数据,传输数据的最大编号同时也会被记录下来,当接收到ACK响应之后,继续从最大数据编号开始传输下一组数据。

c589536627ed77298463525cc9071eef.png

通常而言,我们发送的数据会被维护在一种数据结构中,当接收到ACK回复之后,将这组数据从数据结构中删除,同时新的一组传输数据会加入到数据结构,形成类似滑动的效果,因此成为滑动窗口。


针对滑动窗口可能会出现的两种异常:


ACK丢失:请求数据发送给服务端后,服务端也发出了响应,但是传输过程中ACK响应丢失,这种情况如何解决呢?


解决措施如下:在数据传输的规则中,前面数据没有发送ACK之前(接收到数据并给出响应),后面接收的数据不会给出ACK响应,因此即使前面的数据中ACK丢失,但是获得了后面的响应,也表明前面的数据也被成功接收了,异常消除。

72a3dc934e8fa06e0ab9c5e67eab3851.png

  1. 发送方数据丢失

ee84067f023f2074908c77244ceded7b.png

如图所示,当接收到1-1000的数据之后,1001-2000的数据在传输过程中丢失了,无论你后面其他数据怎样传输,接收端返回的ACK请求都是1001(请求编号为1001-2000的数据),此时后面的传输数据会被存放到缓冲区中,数据发送方接收到三次重复的ACK请求之后,会对缺失的部分数据进行重发,而在缓冲区的数据也按照正常的逻辑进行拼装。


②流量控制:既然存在了滑动窗口来提高数据传输的效率,那么数据数据的大小真的能让发送方毫无限制的进行控制吗?


流量控制就是来限制发发送方滑动窗口的大小,通过接收方返回给发送方的ACK,对发送方滑动窗口的大小进行反制。

733d5354066cfbbc9cef7e1b90d098dc.png

a1039f338fe29b8b26f544b875a25342.png

5dd26dce881fa3c2551258f429d88ace.png



8ae648b74f54d924f0af5ad63fed4030.png

③拥塞控制

根据网络的通畅程度来控制发送窗口的大小

d0d365ce2d48ebddbcb492cf50d9347d.png

其拥塞控制的步骤如下:

在程序刚启动时将容量设置的很小,比如1,如果能够接收到接收方的ACK,则证明数据传输没有问题,后面传输时不断加大滑动窗口的容量

在达到阈值之前,滑动窗口的增量是以指数级别增加的

达到一定的阈值之后以每次加1的方式增加(线性增加)

继续增大的过程中,增大到一定程度发现数据丢包严重,这时说明发生了网络阻塞,此时将容量重新设置为1,阈值也发生变化,此时的阈值为发生网络阻塞的值的一半

不断重复1到4的步骤

整个网络通信的过程中,窗口大小,拥塞的大小都是动态变化的。

245171979383227374824f7d1269fa87.png

综上所述,流量控制的是整个滑动窗口的大小,拥塞控制的也是滑动窗口的大小,那么滑动窗口最后以哪个为准呢?

应该是取两个的最小值。

④延迟应答

61add28c9cae07c17ce51284185b77ca.png

对于请求端发送的数据,接收方并不是一条一条的回答,通常会采用两种策略:①每次回应ACK相隔一定的条数,比如每两组请求消息回应一组ACK.....

②每隔一定的时间回应一次ACK

如果按照上面的策略,如果是3组请求数据,可以采用每隔一定的时间回应一次ACK

具体的数量和超时时间,不同的系统有所差异,一般是N(请求数据发送的组数)取2,超时时间为200ms

image.png

⑤捎带应答

c22296de8bce43704da3e5e5ca7d60d6.png

⑥面向字节流

928d2f8f0da905db7af586a5e8c94874.png

57882bd331ae3810cf93a73ea86516a1.png

⑦TCP异常情况:


程序崩溃:操作系统回收进程资源,其中包括文件描述符表,主要是调用socket的close()方法,之后触发FIN操作,进而开始进行四次挥手,这和普通的四次挥手没有区别


正常关机:系统强制关闭所有进程,系统释放资源,执行流程和程序崩溃类似。


主机掉电:主要分成了两种情况:


①接收方掉电


发送方并不知道接收方掉电,继续发送SYN请求,同时等待ACK响应,但是没有收到ACK响应,这时候触发超时重传,在多次触发超时重传之后没有收到ACK响应,这时请求方就尝试连接重置(RST标志位),连接重置失败,此时就断开连接。


e999df39108955c0c4961b20e72ae9ca.png

②发送方掉电

在一般的长连接中,客户端与服务端会维护一个心跳包(客户端每隔一秒给服务端发送数据,证明自己人仍然存活),如果10s服务端仍然没有收到客户端发来的数据,这时候就认为客户端挂了,此时断开连接,等待客户端回复后,重连即可

断网

与主机掉电情况类似,只不过主机仍然正常运行


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
14天前
|
算法 数据可视化 图形学
网络通信系统的voronoi图显示与能耗分析matlab仿真
在MATLAB2022a中,该程序模拟了两层基站网络,使用泊松分布随机生成Macro和Micro基站,并构建Voronoi图。它计算每个用户的信号强度,选择最强连接,并分析SINR和数据速率。程序还涉及能耗计算,包括传输、接收、处理和空闲能耗的分析。Voronoi图帮助可视化网络连接和优化能源效率。
|
24天前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
32 0
|
24天前
|
存储 消息中间件 缓存
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
34 0
|
10天前
|
网络协议 程序员 定位技术
学习网络的第一步:全面解析OSI与TCP/IP模型
**网络基础知识概览:** 探索网络通信的关键模型——OSI七层模型和TCP/IP五层模型。OSI模型(物理、数据链路、网络、传输、会话、表示、应用层)提供理论框架,而TCP/IP模型(物理、数据链路、网络、传输、应用层)更为实际,合并了会话、表示和应用层。两者帮助理解数据在网络中的传输过程,为网络设计和管理提供理论支持。了解这些模型,如同在复杂的网络世界中持有了地图。
17 2
|
13天前
|
网络协议 安全 Python
python实现对网络流量分析
Python提供多种工具进行网络流量分析,如`pcap`库用于实时捕包,`dpkt`库用于解码数据包,以及`Scapy`库进行高级分析。
|
21天前
|
监控 网络协议 安全
Socket网络编程中的常见应用场景与实例分析
Socket网络编程中的常见应用场景与实例分析
|
21天前
|
安全 算法 Java
扩散模型在社交网络分析中的实际应用案例
扩散模型在社交网络分析中的实际应用案例
|
24天前
|
JSON 数据可视化 API
技术心得:如何用Python和API收集与分析网络数据?
技术心得:如何用Python和API收集与分析网络数据?
23 2
|
24天前
程序技术好文:计算机网络(九)——STP原理
程序技术好文:计算机网络(九)——STP原理
17 1
|
6天前
|
JSON 数据挖掘 API
在会议系统工程中,Python可以用于多种任务,如网络请求(用于视频会议的连接和会议数据的传输)、数据分析(用于分析会议参与者的行为或会议效果)等。
在会议系统工程中,Python可以用于多种任务,如网络请求(用于视频会议的连接和会议数据的传输)、数据分析(用于分析会议参与者的行为或会议效果)等。