网络原理---TCP/IP

活动发起人@小虚竹 想对你说:

这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!我们一起发掘写作的魅力,书写出属于我们的故事。我们诚挚邀请你参加为期14天的创作挑战赛!

提醒:在发布作品前,请将不需要的内容删除。

1.应用层

我们之前编写完了基本的 java socket ,要知道,我们之前所写的所有代码都在应⽤层,都是为了 完成某项业务,如翻译等。关于应⽤层,我们在讲解完毕基本的 TCP/IP 协议之后,我们会单独来进 ⾏讲解。

2.传输层

负责数据能够从发送到传输到接收端。

2.1 再谈端口号

端口号标识了一个主机上进行通信的不同的应用程序。

在TCP/IP协议中,⽤"源IP","源端⼝号","⽬的IP","⽬的端⼝号","协议号"这样⼀个五元组来标识⼀个 通信(可以通过netstat-n查看);

端⼝号范围划分

• 0-1023:知名端⼝号,HTTP,FTP,SSH等这些⼴为使⽤的应⽤层协议,他们的端⼝号都是固定的.

• 1024-65535:操作系统动态分配的端⼝号.客⼾端程序的端⼝号,就是由操作系统从这个范围分配 的.

2.2UDP协议

UDP协议格式

• 16位UDP⻓度,表⽰整个数据报(UDP⾸部+UDP数据)的最⼤⻓度; 如果校验和出错,就会直接丢弃;

UDP的特点:

  • 无连接:知道对端的IP和端⼝号就直接进⾏传输,不需要建⽴连接,
  • 不可靠传输:没有确认机制,没有重传机制;如果因为⽹络故障该段⽆法发到对⽅,UDP协议层也不会给应 ⽤层返回任何错误信息;(如何理解这里的不可靠,⾯向数据报 应⽤层交给UDP多⻓的报⽂,UDP原样发送,既不会拆分,也不会合并;)
  • 面向数据报:不能够灵活的控制读写数据的次数和数量
  • 全双工

我们接下来了解UDP报头,我们所熟知的HTTP协议的报头是文本格式的,UDP/TCP/IP的报头是二进制格式的。

长度

整个UDP数据报长度(报头+载荷),长度属性也是两个字节,表示范围0~65535(64KB).

端口号

一个端口号的取值范围是0~65535,实际上一般把1024以下的端口保留,我们写代码都用1024~65535这个范围的。服务器的端口是程序员指定的(提前指定好,客户端才能访问到),客户端的端口是系统自动分配的空闲端口(如果提前指定了,可能会与你客户端上的程序起冲突)。

校验和

验证数据是否发生修改,之前我们将HTTP的数字签名是为了防止黑客篡改(防人),但UDP的校验和不是为了防人,和安全性无关,而是为了防止出现运输过程中的"比特翻转"(即1变0,0变1)。

发送之前,先计算一个校验和,把整个数据包的数据都代入,把数据与校验和一起发送给对端,接收方收到之后重新计算一下校验和,和收到的校验和进行对比(UDP发现校验和不一致,就会直接丢弃)。UDP的校验和使用了CRC方式来进行校验(循环冗余校验),把每个字节(除了校验和位置的部分之外),都当做整数,进行累加,溢出来也没有关系,继续加最终得到结果,crc校验和传输到对端,数据出现错误了,对端再次 计算的校验和就会和第一个校验和不以样。

认为两个原始数据相同,使用相同的校验和算法,得到的校验和也应该是相同的,反之,两个校验和相同,原始数据一定也相同(可能存在变数)。

UDP使⽤注意事项

UDP总长度最大是64KB,可以表述为UDP总长度达到64KB或UDP携带的载荷长度达到64KB上限。

我们注意到,UDP协议⾸部中有⼀个16位的最⼤⻓度.也就是说⼀个UDP能传输的数据最⼤⻓度是 64K(包含UDP⾸部). 然⽽64K在当今的互联⽹环境下,是⼀个⾮常⼩的数字.如果我们需要传输的数据超过64K,就需要在应⽤层⼿动的分包,多次发送,并在接收端⼿动拼装。

2.3TCP协议

TCP协议特点:有链接,面向字节流,可靠传输,全双工。

TCP协议段格式

16位源端口号/16位目的端口号:传输层的核心内容;

4位首部长度:表⽰该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最⼤⻓度是15* 4=60。

选项:选项的存在,导致tcp报头长度是可变的。

保留6位:TCP报头中就预留了一些"保留位",现在先不用,但是先占个位子。

:TCP最核心的6个标志位.ack为1,表示是应答报文。

16位校验和:用来校验数据是否出现错误.

针对确认应答中的情况,给数据进行编号,其中确认序号只在应答报文中才生效。

TCP的核心机制

可靠性:此处的可靠性,不是说A给B发一个消息,B100%能收到,而是A给B发了消息之后,尽量让B收到消息。

TCP核心机制一:确认应答

保证可靠性的一个关键前提,发送方知道自己的数据是否被对方收到,需要对方给返回一个"应答报文"(acknowledge.ack),发送方知道应答报文,就可以确认对方收到了。

举个例子,我们用短信给别人发送多条消息时,正常情况下,如图所示

但是在网络上会出现后发先至的情况,如图所示,这种情况会引起误解,

那么针对这种情况,我们又该如何解决,接下来我们介绍一下TCP的解决方案

TCP将每个字节的数据都进行了编号,即为序列号。上述列子编号如上图所示:

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

1.TCP是面向字节流的,在编号时,不是按照用条、2条来编号的,而是按照"字节"的方式来编号的,每个字节都分配一个编号,编号是连续递增的。

一个TCP的载荷是由多个字节构成的,需要多个编号,那么此处的序号该怎么填写:序号字段填写载荷部分的第一个字节的序号,序号连续递增;确认序号填法是把收到的载荷数据的最后一个字节序号+1。

2.引入序号之后,接收方就可以根据序号对数据进行排序,TCP需要先处理后发先至的情况,确保应用程序通过socket api读到的数据顺序(即确保代码里读到的数据和发送方写入的数据顺序一致)是正确的。

3.TCP报头不参与排序,序号、确认序号都是针对载荷的,TCP在接收方这里会安排"接收缓冲区",(内存,操作系统内核里),通过网卡读到的数据,先放到缓冲区中,后续代码里调用read,也是从接收缓冲区来读的。

4.在接收缓 冲中,根据序号来排序,序号小的在前面,大的在后面,确保前面的数据已经到了,然后read才能接触阻塞,如果是后面的数据先到,read会继续阻塞,不会读取到数据。

TCP核心机制二:超时重传

1.超时重传是针对丢包的情况做出处理,这里首先会设置一个超时时间,

比如A给B发送数据等B的回应,如果达到等待时间上限,还没有收到ack,A就认为传输过程中发生丢包情况。这里的丢包可能是A给B发生的数据丢了或者B给A返回的ack丢了。

2.为什么会发生丢包现象?

因为网络结构是非常复杂的,数据报经过某个路由器,交换机转发的时候,该路由器、交换机已经非常繁忙了,导致当前所需要转发的数据量超出路由器、交换机的转发能力上限,此时,数据报会消耗更多的时间,才能到达对方,跟糟糕的是,数据报太多,路由器、交换机根本处理不过来,接收缓冲区已满,只能丢弃。

3.丢包是不能避免的客观现象,而重传是有效对抗丢包的手段。

4.如何判断是否丢包?

引入超时时间来判断是否丢包,TCP中,判断超时时间的阈值,不是固定数值,是动态改变的。

假设当前A向B发送数据,丢包时间的阈值是T,当A给B传输发生超时之后,就会延长这个时间阈值,即延长这个时间,但不是无休止的,超时次数达到一定程度或等待时间达到一定程度,就会认为网络出现严重故障,放弃这一次传输。

5.针对A给B发生的数据丢了或者B给A返回的ack丢了这两种情况,发送方A区分不了当前是那种情况,所有都重传。

情况1

A给B发生的数据丢了,直接重传就可以了。

情况2

对于这种情况,B已经收到了一份数据,如果重传,B就会收到两份一样的数据,如果tcp不处理,可能会使应用层读到两次一样的数据,所以tcp会在内部进行去重操作,此时根据序号,在接收缓冲区中寻找,如果存在,就直接丢弃;如果不存在,才放进去。

注:确认应当和超时重传是TCP最核心的两个机制,保证了TCP能够进行可靠运输

相关推荐
阿巴~阿巴~3 分钟前
信号产生机制全解析:从硬件异常到软件触发的深度探索
linux·运维·服务器
sky北城2 小时前
linux基本系统服务——DNS服务
linux·运维·服务器
William一直在路上4 小时前
KONG API Gateway中的核心概念
网络·gateway·kong
张人玉4 小时前
WinForm之ListBox 控件
服务器·windows·microsoft
人生匆匆5 小时前
linux ext4缩容home,扩容根目录
linux·运维·服务器
sakoba7 小时前
Docker学习其二(容器卷,Docker网络,Compose)
运维·网络·学习·docker·容器·基础
A了LONE7 小时前
cv弹窗,退款确认弹窗
java·服务器·前端
惜.己8 小时前
appium中urllib3.exceptions.LocationValueError: No host specified. 的错误解决办法
网络·appium
吉凶以情迁9 小时前
window服务相关问题探索 go语言服务开发探索调试
linux·服务器·开发语言·网络·golang
卍郝凝卍9 小时前
云上服务器常见的存储方式和类型
大数据·服务器·数据库