【Java网络编程】IP网络协议与TCP、UDP网络传输层协议

news2024/11/18 22:53:18

1.1、IP协议

   当应用层的数据被封装后,想要将数据在网络上传输,数据究竟要被发往何处,又该如何精准的在网络上定位目标机器,此时起到关键作用的就是“IP协议”。
IP协议的作用在于把各种数据包准确无误的传递给目标方,其中两个重要的条件是IP地址和MAC地址。其中IP地址就是所有主机在网络通信中的唯一标识,但由于IP地址是稀有资源,不可能每个主机都拥有一个IP地址,因此路由器里面会记录我们主机的MAC地址,通常的IP地址是路由器根据MAC地址生成的,而MAC地址是全球唯一的。

举例:IP地址就如同是物流线路上的驿站地址,而MAC地址就是具体货架上货物的位置。

之前的IP地址采用的IPv4格式,目前大部分主机都已向IPv6过渡。

1.1.1、IP地址的组成与分类

   IP地址一般由网络标识(NetID)主机标识(HostID) 两部分组成,其中网络标识对应着网络地址,表示其局域网属于互联网中的哪一个网络;主机标识对应着一台机器的主机地址,表示机器属于该局域网络中的哪一台主机。
通常情况下,一个IP存在四组数字,每组数字对应着八位二进制数字(一个IP地址共计32Bit),每组之间分别用.隔开,其中不同类型的IP地址,表示网络标识和主机标识的数字段也不同,目前的IP地址主要可分为A、B、C、D、E五大类,如下:

IP地址分类

A类IP

A类地址由8位网络标识+24位主机标识组成,也就是之前的四组数字中,第一组表示网络地址,而后三组代表主机地址。网络地址的最高位,即首位必须为0,其中0127都为保留位,因此AIP的网络地址范围为1~126(1.0.0.0~126.0.0.0),也就代表着可用的A类网络有126个,每个网络中最大可容纳一千多万台主机(224-2)。

PS:为什么A类网络的地址范围是1~126呢?
因为AIP中用8bit表示网络标识,首位需要保留为0,因此剩下的7bit能够表示的最大数字为127,末位127也需保留,因此A类网络地址的取值范围为1~126

示意图如下:

A类IP-示意图

例如32.44.128.5这个地址,其中第一段代表网络地址,剩余三段表示网络中的主机地址。

B类IP

B类地址由16位网络标识+16位主机标识组成,因此IP中第一段和第二段都为网络标识,其中前两位为保留位1、0,因此BIP的网络地址取值范围为128~191(128.0.0.0~191.255.0.0),总计可用的B类网络数量为16382个,每个网络中可容纳6万多台主机(216-2)。BIP组成示意图如下:
 

B类IP-示意图


例如128.123.11.32这个地址,其中前两段为网络地址,后两段表示网络中的主机地址。

C类IP

C类地址由24位网络标识+8位主机标识组成,也就是说,整个IP地址中,前三段都为网络地址,最后一段为主机地址。C类地址中,前三位都为保留位,即C类网络的最高位必须为1、1、0,因此C类网络地址的取值范围为192-223(192.0.0.0~223.255.255.0),粗略计算下来,C类网络的数量可达209万左右,每个网络中允许存在254台主机(28-2),组成示意如下:
 

C类IP-示意图


192.0.0.121这个IP,前三段为网络地址,最后一段则为网络中的主机地址。

D类IP

D类和后续的E类属于特殊的IP地址,D类地址被称为广播或组播地址,其最高位必须是1、1、1、0,因此取值范围为224~239(224.0.0.0~239.255.255.255),如下:

D类IP-示意图

E类IP

E类地址则属于保留的地址,为以后接入更多的网络预留的IP,其最高位必须为1、1、1、1,即EIP第一段的取值范围为240~255(240.0.0.255~239.255.255.254)

E类IP-示意图

255.255.255.255这个全1IP属于特殊含义的地址,表示当前子网的广播地址,如同全0IP0.0.0.0代表本机地址一样,带有特殊的含义。

IP分类小结

   因不同类型的网络IP规模不同,所以它们也分别应用于不同的场景,如:

  • AIP适用于大型网络,由于单个网络中可容纳的主机数非常巨大,因此常被保留给政府机构使用。
  • BIP适用于中型网络,一般会被分配给公益组织、中大型企业等。
  • CIP适用于小型网络,这种IP适用于所有需要网络的个体和小集体,如网吧、家庭、个人电脑等。
  • DIP用于组播。
  • EIP用于保留和实验。
1.1.2、子网掩码

   子网掩码又被称为网络掩码、地址掩码、子网络遮罩,它的作用主要有两个:

  • 一、区分IP中网络地址和主机地址。
  • 二、划分子网,扩大网段内的可用IP数目。

但默认的子网掩码值也并非都相同,不同的网络类型存在不同的默认掩码,如:

  • A类网络的默认子网掩码:255.0.0.0
  • B类网络的默认子网掩码:255.255.0.0
  • C类网络的默认子网掩码:255.255.255.0

一个子网掩码决定着一个子网(独立的单个网络)内可容纳的主机数量,计算公式为:可容纳的主机数量=(2n次方)-2。这个n可以理解为二进制掩码中0的数量,例如:

  • A类默认掩码:255.0.0.0转换为二进制为:11111111.00000000.00000000.00000000,后面有240,因此可容纳的主机数量为(224次方)-2,即16777214台主机。
  • C类默认掩码:255.255.255.0转换为二进制为:11111111.11111111.11111111.00000000,后面存在80,因此C类网可容纳主机数量为(28次方)-2,即254台主机。
修改子网掩码为局域网扩容

   在中型企业中,经常会碰到一个问题,公司使用C类网,因此子网内可容纳的主机(电脑)数量为254台,但实际公司的电脑可能超出这个数量,如存在440台电脑,那此时如何更改路由器的设置可以让440台电脑同时上网呢?

  • 方案一:增加路由器的数量,更改多个路由器配置。
  • 方案二:通过改变子网掩码的方式为局域网扩容。

,对于第一种方案需要增加经济成本,因此可以暂不考虑。来看看第二种方案,此时将子网掩码修改到多少合适呢?计算过程如下:

  • ①:主机数量/子网可容纳主机的最大数,再向上取整,即:
    • 440/254≈1.73,向上取整结果=2,也就是容纳440台电脑需要2个网段。
  • ②子网掩码决定着子网内可容纳的主机总量,那么设:2N次方≈主机数量,求N
    • 2N次方=440,可算出N>8,即N=9最合适,因此掩码低位应当存在90
    • 即:11111111.11111111.11111110.00000000,转换为十进制:255.255.254.0
    • 因此最终计算出子网掩码为255.255.254.0最合适。

此时假设路由器的LAN口配置是197.118.0.1,那根据第一步计算出的网段数量,分配两个子网段,197.118.0.1~197.118.1.254即可满足需求,采用这种更改子网掩码的方式,就在不增加路由器的情况下,也能达成了为局域网增加可用IP数的需求。

最终可用IP范围为:197.118.0.1/23,可用IP地址共计510个。
嗯?xxx/23是什么东东?其实这个值是子网掩码的简写方式,之前算出来的子网掩码为255.255.254.0,转换为二进制,一共存在231,因此可以简写为xxx/23

如何判断两个IP处于同一个网段

两个IP处于同一网段的前提是:两个IP的网络标识必须一致,那如何计算网络地址呢?

网络地址 = IP地址 “位与” 子网掩码。

如C类网197.118.0.198、197.118.1.114两个IP,子网掩码为255.255.254.0,如何计算网络地址?首先需要将掩码与IP全部都转换为二进制,如下:

  • 197.118.0.19811000101.01110110.00000000.11000110
  • 197.118.1.11411000101.01110110.00000001.01110010
  • 255.255.254.011111111.11111111.11111110.00000000

首先将197.118.0.198网络部分(前三段)的二进制值同掩码进行位与运算,最终可以计算出:

11000101.01110110.00000000,转换为十进制为197.118.0

紧接着再197.118.1.114网络部分的二进制值同子网掩码进行位与运算,计算结果:

11000101.01110110.00000000,转换为十进制为197.118.0

最终可得到结果:197.118.0.198、197.118.1.114的网络地址都为197.118.0,代表着这两个IP处于同一个网段。

子网掩码小结

子网掩码这块的内容,如果你不是专门做网络相关的工程师,哪适当了解即可,如不理解其内容也无关紧要,作为软件开发者并不需要太过深入研究。

1.1.3、IP协议核心流程

   经过上述内容学习后,我们已经对IP协议中的IP组成、分类、计算等知识已经建立起了基础,接下来在重点看看IP协议的核心流程。IP协议核心主要包含IP寻址和路由控制。

   前面曾提及:网络上任何一台主机都会存在自己的IP地址,那么当应用层数据被封装后,能够精准定位到目标主机的关键原因就在于IP,可以通过IP地址在网络中进行寻址,从而让数据到达目的主机。

但在实际的网络通信过程中,可能有时数据发送的链路非常遥远,如你从中国向日本网友发送一条数据,那么由于一些网络抖动、物理介质损坏都会导致数据丢失。但此时又该如何确保数据“安稳”到达目的地呢?

为了防止数据由于介质损坏或网络抖动等原因丢失,因此会在数据的传输链路中加入一些“中转站”,也就是所谓的“路由器”,一方面可以备份数据,查看数据是否丢失,如果丢失会重新发送,另一方面也可以控制数据的转发。当然,这个控制数据转发的过程也被称为“路由控制”。

正因为路由控制的存在,所以即使网络复杂多变,也能够通过路由器的控制将数据“安稳”送达至目的主机。

但因数据传输过程中,数据从发送方到接收方之间存在的链路是不可预估的,因此数据传输的链路上可能会分布很多路由器。本质上数据在链路中传输,就是一个个路由器相互之间交换数据报的过程,当然,这个过程也被称为“”。

跳:数据包经过一台路由器就是一跳。
好比一个网络中存在四个路由器:A、B、C、D,如果局域网A中的主机要给局域网D中的主机发送数据,从理论上来说就会经过B、C、D三台路由器,也就是会经过三跳。

哪当数据到达某个路由器后,它如何知道“下一跳”该去往何处呢?此时中转的路由器就会解析收到的数据报,然后从中解析出IP数据报,然后查询自身的路由表,从而选择“下一跳”该走的路线,最终不断重复该过程直至数据到达目标主机。这种多次转发数据的过程也被称为“多跳路由”。

1.1.4、IPv4与IPv6

   目前的网络几乎大部分还是基于IPv4版本,但同时大部分应用程序也开始支持IPv6IPv6是“Internet Protocol Version 6(互联网协议第6版)”的缩写,是用于替代IPv4的下一代IP协议,也就是下一代互联网的协议。

   IPv6相较于IPv4而言,主要不同点在于:

  • ①地址空间不同,IPv4地址采用32位长度,IPv6的地址则采用128位长度。
  • IPv6的路由表会比IPv4更小、更精细。
  • IPv6的组播支持以及对流的支持要强于IPv4
  • IPv6的安全性更高,使用IPv6的用户可对网络层数据进行加密。
  • 协议扩充不同,IPv6允许协议进行扩充,而IPv4不允许。

前述的IP协议分析都是基于IPv4版本而言的,因为目前主流的网络版本还是IPv4,但如今也逐步向IPv6过渡。

1.2、“面向连接”的TCP可靠传输协议

   TCP(Transmission Control Protocol)传输控制协议是面向连接的可靠传输协议,是位于传输层的核心协议之一,在不可靠的互联网络上,IP协议只提供了简单不可靠的包交换,但网络中不同主机之间经常需要一种可靠的、类似于管道一样的连接、流机制,去稳定传输一些数据,如视频、音频、图片等大文件数据。
因此TCP应运而生,TCP协议是为了在不可靠的互联网络上提供可靠的端到端之间,字节流传输而专门设计的一个传输协议,TCP中采用字节流传输数据。

1.2.1、TCP协议简介

先来看看TCP的报文头结构:
 

TCP报文头


TCP报文头结构中的各字段释义如下:

  • ①源端口/目的端口:指数据发送方的应用进程端口号及接收方的进程端口号。
  • ②序号:TCP为了保证数据的可靠传输,会对分段数据标注序号,用于组装和确认数据的正确性。
  • ③确认序号:当接收方收到接收到本次数据时,下次需要发送的数据段序号。
  • ④首部:表示TCP报文头的长度,因为TCP头长度可变性,因此需要在头信息中声明每个头的长度。
  • ⑤保留位:预留一些空间给未来拓展时使用。
  • URG:表示本次发送的报文数据中是否紧急数据。
  • ACK:确认信号,当报文中ACK=1的时候表示正确或同意。
  • PSH:表示接收方应该尽快将这个报文交给应用层,为后续数据腾出空间,不要停留在缓冲区。
  • RST:如果收到RST=1的报文,说明与主机的连接出现严重错误(如主机崩溃),必须释放连接,然后重新建立连接。
  • SYN:建立一个新连接,SYN=1表示这是一个请求建立连接的报文段。
  • FIN:断开一个连接,FIN=1表示通知告知对方本段要关闭连接了。
  • ⑫窗口大小:表示现在允许发送的数据量,当到达此值,需要ACK确认后才能继续发送数据。
  • ⑬效验和: 通过CRC算法提供额外的可靠性,用于效验数据正确性。
  • ⑭紧急指针:标记紧急数据在数据字节流中的位置。
  • ⑮选项:这块属于动态的可选择参数。主要选项如下:
    • 最大报文段长度、窗口扩大、时间戳。
  • 数据:报文段传输的数据内容(不属于TCP报文头的范畴内)。

   当应用层向传输层传递数据时,TCP会首先对数据流进行分段,将大的数据拆分成一个个的数据报文段,然后会将封装好的数据包传递给网络层的IP层。同时,为了防止数据在网络传输中丢包,TCP也会对每个数据包分配一个序号,当接收方成功收到发送的数据后,会返回一个ACK确认,如果发送方在规定的合理时间(RTT)内未收到接收方的ACK,那么对应的数据包会被认定为已丢失,发送方会将该段数据重新传输。

当数据接收完成后,TCP会用校验和函数来检验数据是否正确,在发送方和接收方都需要计算该值,发送方计算后会将该值放在TCP头中携带发送,接收方接收到数据后,也会再次计算该值,再与报文头中的值进行比对,确认数据的正确性。

1.2.2、连接管理机制 - 三次握手与四次挥手

   由于TCP是基于管道连接式通信的协议,因此在数据传递之前,必须要先建立连接,当数据传输完毕后,也必须要关闭连接。因此,这就引出了面试过程中人尽皆知的问题:“为什么TCP是三次握手,四次挥手!

想要了解清楚这个问题的答案,那么得先了解TCP建立与关闭连接的过程。

TCP的三次握手

   所谓的TCP三次握手,其实是指TCP建立连接的过程,因为TCP属于可靠性的传输协议,因此在发送数据前必须要先确保发送/接收数据的双方状态正常,因此需要经过“三次握手”的过程,具体如下:

TCP建立连接-三次握手

  • ①客户端向服务端发送建立连接的数据包SYN=1,seq=x,然后进入syn-send等待确认连接状态。
    • SYN=1:代表请求建立连接。
    • seq=x:当前数据包的序号。
  • ②服务端接收到请求建立连接的数据包后,允许建立连接的情况下,会返回响应报文SYN=1,ACK=1,seq=y,ack=x+1给客户端。
    • SYN=1TCP是双全工协议,因此服务端也需向客户端发送SYN=1信号。
    • ACK=1:确认客户端建立连接的请求。
    • seq=y:表示当前服务端返回给客户端的序号。
    • ack=x+1:确认客户端序号x之前的请求都已收到。
  • ③因为是双全工协议,连接是双向的,因此客户端也需确认一下服务端的连接请求,收到服务端的SYN=1后,也需返回ACK=1,seq=x+1,ack=y+1的数据包。
    • ACK=1:表示确认服务端的连接建立请求。
    • seq=x+1:当前数据包的请求序号。
    • ack=y+1:确认服务端序号y之前的数据都已成功接收。

经过如上三个步骤,客户端和服务端双方之间确认请求后,连接会成功建立,紧接着双方都会处于estab-lishen状态,数据可以正常传输。

当然,这个过程略微有些难理解,换个日常生活的例子来快速理解一遍!

  • ①特种兵-竹子:我是竹子,熊猫收到请回答!收到请回答!
  • ②指挥部-熊猫:熊猫收到,我是熊猫,竹子能收到吗?收到请回答!
  • ③特种兵-竹子:竹子收到!竹子收到!
  • 通话开始.........
TCP的四次挥手

当“三次握手”完成后,客户端和服务端之间会成功建立连接,从此开启双方端到端之间的数据传输,当一方数据传输完成后,会尝试中断连接,因此又会经历“四次挥手”的过程,如下:

TCP断开连接-四次挥手

  • ①客户端完成数据传输后,会发出FIN=1,seq=u关闭连接的报文,然后等待服务端响应。
    • FIN=1:代表请求关闭连接。
    • seq=u:请求序号。
  • ②服务端收到客户端的“关闭”请求后,会给客户端返回确认关闭的报文:ACK=1,seq=v,ack=u+1
    • ACK=1:确认客户端“关闭连接”的请求。
    • seq=v:请求序号。
    • ack=u+1:确认客户端序号u及其以前的数据都已成功接收。
    • 客户端传输完成数据后,会告诉服务端自己要关闭连接了;
    • 但服务端可能数据还未传输完成,因此会继续传输自己的数据,直至自身的数据也传输完成后,也会告诉客户端:自己也要关闭连接了。
  • ③服务端传输完成自己的数据后,向客户端发送关闭连接的报文:FIN=1,ACK=1,seq=w,ack=u+1
    • FIN=1:表示自己也要“关闭连接”了。
    • ACK=1:确认收到了之前的数据。
    • seq=w:请求序号。
    • ack=u+1:确认客户端序号u之前的数据都已成功接收。
  • ④客户端接收到服务端“关闭连接”的请求后,给服务端响应确认报文:ACK=1,seq=u+1,ack=w+1
    • ACK=1:确认服务端“关闭连接”的请求。
    • seq=u+1:请求序号。
    • ack=w+1:确认服务端序号w之前的数据都已成功接收。

前面提及过,因为TCP是双全工的协议,因此双方都可以主动释放连接,在TCP中,当一方数据传输完成后,就会主动关闭连接,也就会经历“挥手”的过程,同样我们也可以举个通俗一些的例子来认识这个过程:

  • ①特种兵-竹子:竹子汇报完毕,请指示!
  • ②指挥部-熊猫:指挥部收到!..&*/?..!^...继续说完自己要交代的任务。
  • ③指挥部-熊猫:这里是熊猫,任务已指示完毕!
  • ④特种兵-竹子:竹子收到!
  • 中断通话.........

三次握手是指TCP建立连接需要发送三个数据包,主要目的是在于:为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。

四次挥手是指TCP关闭连接时需要发送四个数据包,主要目的在于:当客户端发送完数据后,给服务端发送“我要关闭连接了”的请求,然后服务端告知客户端收到了“关闭请求”,但此时服务端会继续向客户端传输未发送的数据,客户端也照旧可以接收服务端的数据,直到服务端的数据传输完成后,服务端也会发出“关闭连接”的请求,客户端同意后,最终才会断开连接,从而保证数据正常可靠的交互。

本质上“三次握手与四次挥手”就是在指TCP建立与关闭连接的过程,搞明白建立和关闭连接的过程后再来看看最开始的问题:“为什么TCP是三次握手,四次挥手!

为什么TCP是三次握手,四次挥手

   因为建立连接“握手”时,当服务端接收到“客户端想与服务端建立连接”的请求后,可以立马返回“同意+与客户端建立连接”报文,客户端也确认建立连接后,就可以称为“握手完成”。
但关闭连接时的“挥手”,因为一方数据传输完成后就会提出关闭连接,不过另外一方可能还依旧存在数据未发送完成,因此服务端就不能在“确认关闭”连接的时候,也同时发出“关闭连接”的请求,因为自己的数据还没发送完成呢,所以会等到自身的数据全部传输后,再主动向客户端发起一次“关闭连接”的请求,等待客户端“确认关闭”后,从而完成整个“挥手”动作。

1.2.3、TCP中的沾包问题

   要理解“TCP沾包”问题之前,首先要理解TCP传输数据的方式。TCP在传输数据时,会给每个分割后的报文段分配一个序号,接收方在收到数据后,会按照序号排好,然后将其放置在TCP缓冲区中。同时TCP为了提升传输速度,若连续几次发送的数据都很少,TCP会根据优化算法把多个数据合并成一个包发出。

沾包问题:多个数据包在一块儿,无法确定每个数据包之间的分割边界,因此从应用层的角度看来,就好像多个数据包“沾”在了一起。

   对于TCP传输层而言,发送方和接收方都有可能造成数据沾包问题。

   发送发导致的数据沾包问题:TCP为了优化传输速度,往往会等收集到足够多的数据后才发送一包数据,因此发送发传输的数据就出现了沾包问题。
还有一种情况则是:当需要发送的数据大于MSS规定,那么TCP就会对数据包进行拆包,一个数据包会被分开传输,最终导致数据出现沾包问题。

   接收方导致的数据沾包问题:TCP中,如果数据被接收后,应用程序没有及时读取缓冲区中的数据报文,就会导致缓冲区中堆积大量的报文数据。这种情况下,站在TCP层的角度而言,看到的是一个个的数据报文依次排列着,但对于应用层的程序来说,看到的就是一串连续的字节流数据,应用程序无法知道每个数据包之间的分割边界,站在应用层的角度来看,所有的数据包就好像都“沾”在一起了一样,应用程序根据预先设定好的大小从缓冲区中接收数据,最终会一次性读取到多包数据。

沾包问题解决方案
  • ①当使用TCP短连接时,不必考虑沾包问题。
  • ②当发送无结构数据,如文件传输时,也不需要考虑沾包问题,因为这类数据只管发送和接收保存即可。
  • ③如果使用长连接,那么则需要考虑沾包问题:
    • 如果发送的报文都是相同的结构,那么可以在首部中添加数据长度,接收方根据首部中记录的数据大小读取数据。
    • 将每个数据包封装成固定长度,不够的用0补齐,接收方每次按照固定大小读取数据即可。
    • 在数据之间设置边界,比如添加特殊符号,这样接收方收到数据时,根据特殊符号分割数据即可。
1.2.4、TCP协议中的其他核心概念

   因为TCP既要保证可靠性,同时又要尽可能提高传输性能,所以整个TCP设计的尤为复杂,牵扯出的概念也很多,比如为了保证数据的可靠传输,TCP中提供的机制:

  • 效验和:数据接收完成后进行效验。
  • 序列号:数据按顺序传输和接收。
  • 确认应答:收到数据之后返回ACK应答。
  • 超时重试:超出规定时间后,发送方未收到ACK应答,则会重新再次发送数据。
  • 连接管理:建立和管理连接时,都会经历三次握手、四次挥手确保数据可靠传递。
  • 流量控制:TCP根据接收端的处理能力, 来决定发送端的发送速度,避免丢包。
  • 拥塞机制:TCP采用慢启动机制,由于网络拥塞情况不确定,刚建立连接时会先发送少量数据的包,“摸清楚”网络拥塞程度后,再优化成合适的数据包大小传输。

在确保了数据可靠传输的同时,TCP也提供了一堆机制尽可能提高数据传输性能:

  • 滑动窗口:因为接收一条数据,返回一个ACK这种应答机制大大影响了传输效率,因此TCP中引入了一个新概念:窗口,窗口大小是指无需等待ACK就可继续发送数据的最大值,当收到第一个ACK确认应答后,窗口向后移动,发送后续的数据,因为这个窗口不断向后滑动,所以叫做滑动窗口。
  • 快速重传:结合上述的滑动窗口机制,当某个数据出现丢包时,接收方会持续向发送方传输相同的ACK应答序号,当发送方连续三次接收到相同的应答序号时,就会对该序号的数据报进行重发。
  • 延迟应答:接收方应答速度越快,那么窗口会越小,而延迟应答就是指:接收端稍等一会儿后再发送应答信号,应答速度越慢,窗口越大,网络吞吐量就越大,传输效率就越高(但受到数量和时间的限制)。
  • 捎带应答:在一般数据的传输过程中,大多数情况下都是一发一收的过程,因此ACK应答可以“搭数据的顺风车”,和接收方回应的数据报文一起返回,如三次握手中的第二次握手,采用的就是捎带应答机制,ACK应答信号和建立连接的数据报一起发送给了客户端。

同时,TCP协议中,每建立一条连接都会维持九个定时器,可以适当了解:

  • 超时重传定时器:超出规定时间范围后,未收到应答信息,对数据进行重发。
  • 保活定时器:如果已建立的连接超出规定时间后还没有数据交互,则保活定时器超时,向对端发送保活探测包,根据客户端的反馈决定是否继续维持连接,如客户端正常则重置定时器时间,如客户端异常则关闭TCP连接。
  • 持续定时器:也被称为零窗口探测定时器,当接收方缓冲区数据满了之后,会在应答报文中通知发送方将窗口置0,阻止发送方继续发送数据。当缓冲区数据被读取后,会再向发送方发出一个ACK,通知发送方可以继续传输数据,但为了防止该ACK丢失导致死锁现象出现,发送方也会启动零窗口探测定时器,每隔一段时间,发送方会主动发送探测包,迫使接收端响应,从而得知其接收窗口有无打开。
  • ACK延迟定时器:延时应答的定时器,和超市重传定时器功能类似。
  • SYNACK定时器:新建连接时等待ACK应答的定时器,超出时间后会关闭连接。
  • FIN_WAIT2定时器:关闭连接时等待ACK的定时器,超时后会取消“关闭连接”。
  • ER延迟定时器、PTO定时器、TIME_WAIT定时器:这三玩意儿没研究过。

1.3、“面向无连接”的UDP不可靠传输协议

   UDP(User Datagram Protocol)协议是传输层的一个不可靠传输协议,它为应用程序提供了一种无需建立连接就可以发送封装的IP数据包的方法。在传输层中,与TCP协议互补,UDP除了给应用层提供了发送数据包的功能外,几乎没有做任何其他事情。而面向连接的TCP恰恰相反,几乎做了所有的事情。

   刚刚提到过,UDP仅为应用层提供了发送数据报的功能,主要就是指UDPIP协议的扩充:

  • ①建立在IP协议的基础上,扩展出端口号,可使数据分发到具体的应用程序。
  • ②建立在IP协议的基础上,扩展出数据传输过程中的数据差错效验机制。

接下来先看看UDP的报文头结构。

1.3.1、UDP的报文头

UDP报文头


对比TCP复杂的报文头结构,UDP的头部就显得比较简单了,整个头共8字节:

  • ①源端口/目的端口:指数据发送方的应用进程端口号及接收方的进程端口号。
  • ②报文长度:Header+Data的总长度,因为UDP头为8字节,所以该值最小为8
  • 效验和:检测UDP数据报在传输中是否有错,有则丢弃(UDP检验和并非必须的),就算效验时检测出错误,也仅只是丢弃数据包,不会对数据进行纠正,也就是不会重发数据报。
1.3.2、UDP核心流程

   UDP是一个无连接的协议,因此采用UDP传输协议的程序,在传递数据时,不会存在建立/释放连接的过程。当数据需要传输时,会对于应用层的数据简单的封装,也就是加上自己的UDP头后,直接会将数据丢给IP层,然后交由链路传输。

正因为如上特性,因此UDP的传输速度仅受到数据生成的速度、计算机算力和传输带宽的限制。

   在接收端,UDP会把每个消息段放在队列/缓冲区中,程序每次从队列中读一个消息段。当然,接收端收到数据后,也会对数据做效验,但效验完成后,如若数据存在差错,那UDP只会单纯的丢弃该数据包,不会要求发送端重发数据。

因为由于UDP高效的传输性能,因此常备应用在广播通知、音频通话、视频传输等多媒体数据流业务,而且这类业务中,如果有一个数据包丢失,在很短的时间内就会有另一个新的数据就会替换它,因此就算数据传输不可靠也无关紧要。

1.3.3、UDP中的丢包问题

   由于UDP的不可靠传输,因此数据出现丢包是很常见的事情,一般UDP中造成数据丢包的原因主要如下:

  • ①接收端处理数据时间过长,导致不同包之间的数据处理间隔时间过长,造成丢包。
  • UDP单个数据包过大,导致缓冲区快速被填满,接收端程序来不及处理造成丢包。
  • ③发送端数据发送频率过快,接收端处理速度跟不上,从而导致数据丢包。
  • ④发/收双方之间存在网络不稳定,导致数据无法正常分发,从而导致丢包。
  • 一般来说,丢包的原因很简单,要么是网络问题,要么就是接收方处理速度跟不上导致的。
丢包问题解决方案
  • ①如果是数据包过大造成丢包,那么则可以切割数据后分批次发送。
  • ②如果是发送频率过高导致丢包,可以适当控制频率/减小流量,或调大缓冲区。
  • ③如是缓冲区最大了,还是由于处理不过来导致数据丢包,那么可以在程序内再实现一个缓存区,先读取数据到程序中缓存,从而提升接收端的吞吐量。
  • ④如果程序中对于丢包容忍率很低,那么可以自己实现重发机制,或直接切换TCP实现。
1.3.4、TCP与UDP之间的区别
TCPUDP
面向连接面向无连接
可靠信息传输不可靠信息传输
字节流传输报文传输
传输速度慢传输速度快
仅支持点对点通信支持一对一、一对多、多对多通信
具备拥塞机制和流量控制不具备拥塞机制和流量控制
TCP首部至少20个字节UDP首部仅8个字节

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1573353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 378 有序矩阵中第K小的元素

题目信息 LeetoCode地址: . - 力扣(LeetCode) 题解内容大量转载于:. - 力扣(LeetCode) 题目理解 题意很直观,就是求二维矩阵中所有元素排序后第k小的数。 最小堆写法 该写法不再赘述,维护…

好看流光风格个人主页HTML源码

这是一款好看流光风格个人主页HTML源码,感觉挺喜欢的,需要的自行下载! 源码下载 好看流光风格个人主页源码

“进击的巨人”:服务器硬件基础知识解析

引言: 服务器是网络环境中负责处理数据、运行应用程序和服务多用户的高性能计算机系统。了解服务器的硬件构成有助于更好地管理和优化IT资源。 服务器和普通PC的差异: 服务器具有比个人电脑更高的处理能力、稳定性和可靠性,它们通常运行在没…

【JavaEE】浅谈线程(一)

线程 前言线程的由来线程是什么线程的属性线程更高效的原因举个例子(线程便利性的体现) 多线程代码线程并发执行的代码jconsole(观测多线程) 线程的调度问题创建线程的几种方法1)通过继承Thread 重写run2)使用Runnable接口 重写ru…

.NET8 和 Vue.js 的前后端分离

在.NET 8中实现前后端分离主要涉及到两个部分:后端API的开发和前端应用的开发。后端API通常使用ASP.NET Core来构建,而前端应用则可以使用任何前端框架或技术栈,比如Vue.js、React或Angular等。下面是一个简化的步骤指南,帮助你在…

指针 基础知识

本笔记为观看56 指针-指针的定义和使用_哔哩哔哩_bilibili后的学习笔记 指针的定义和使用 1、定义指针 int main () {//1、定义指针int a 10;//指针定义的语法: 数据类型 * 指针变量名;int * p;//让指针记录变量a的地址p &a; //& 为取址符cou…

Mac资源库的东西可以删除吗?mac资源库在哪里打开 cleanmymacx是什么 cleanmymac免费下载

在使用Mac电脑的过程中,用户可能会遇到存储空间不足的问题。一种解决方法是清理不必要的文件,其中资源库(Library)文件夹是一个常被提及但又让人迷惑的目标。Mac资源库的东西可以删除吗?本文旨在解释Mac资源库的作用、…

Java常用函数接口

Java常用函数接口 Java 8 中引入的常用函数式接口,也就是 java.util.function 包中的接口。这些接口提供了一种简洁的方式来定义函数,常用于 Lambda 表达式和方法引用。下面是一些常用的接口: 一、Predicate(断言) …

应用性能分析工具CPU Profiler

简介 本文档介绍应用性能分析工具CPU Profiler的使用方法,该工具为开发者提供性能采样分析手段,可在不插桩情况下获取调用栈上各层函数的执行时间,并展示在时间轴上。 开发者可通过该工具查看TS/JS代码及NAPI代码执行过程中的时序及耗时情况…

c语言之动态内存管理及常见错误分析,柔性数组,内存划分

目录 前言 一:malloc,calloc,realloc,free四大函数 1.malloc 2.free 3.calloc 4.realloc 二:常见错误分析 1.malloc返回值不检查直接使用 2.对动态开辟空间的越界访问 3.对非动态开辟空间free 4.使用free释放动态开辟内存的一部分 5.对…

QAuth 2.0

OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务,通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源,或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解,可以想象OAuth2.0就是在用户资源和第…

多路转接-epoll/Reactor(2)

epoll 上次说到了poll,它存在效率问题,因此出现了改进的poll----epoll。 目前epoll是公认的效率最高的多路转接的方案。 快速了解epoll接口 epoll_create: 这个参数其实已经被废弃了。 这个值只要大于0就可以了。 这是用来创建一个epoll模…

用友U9 存在PatchFile.asmx接口任意文件上传漏洞

声明: 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 简介 用友U9是由中国用友软件股份有限公司开发的一款企业…

FJSP:狐猴优化算法(Lemurs Optimizer,LO)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题(Flexible Job Shop Scheduling Problem,FJSP),是一种经典的组合优化问题。在FJSP问题中,有多个作业需要在多个机器上进行加工,每个作业由一系列工序组成&a…

Linux(Ubuntu)中创建【samba】服务,用于和Windows系统之间共享文件

目录 1.先介绍一下什么是Samba 2.安装,配置服务 安装 配置(smb.conf) 配置用户 3.出现的问题(Failed to add entry for user XXXX) 4.创建文件夹 5.windows访问 1.先介绍一下什么是Samba Samba是一个开源的软…

HTML5.Canvas简介

1. Canvas.getContext getContext(“2d”)是Canvas元素的方法,用于获取一个用于绘制2D图形的绘图上下文对象。在给定的代码中,首先通过getElementById方法获取id为"myCanvas"的Canvas元素,然后使用getContext(“2d”)方法获取该Ca…

剑指Offer题目笔记26(动态规划的基础知识)

面试题88: 问题: ​ 一个数组cost的所有数字都是正数,它的第i个数字表示在一个楼梯的第i级台阶往上爬的成本,在支付了成本cost[i]之后可以从第i级台阶往上爬1级或2级。请计算爬上该楼梯的最少成本。 解决方案一:&…

【简单讲解下epoll】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

Day:004(1) | Python爬虫:高效数据抓取的编程技术(数据解析)

数据解析-正则表达式 在前面我们已经搞定了怎样获取页面的内容,不过还差一步,这么多杂乱的代码夹杂文字我们怎样 把它提取出来整理呢?下面就开始介绍一个十分强大的工具,正则表达式! 正则表达式是对字符串操作的一种…

力扣Lc28---- 557. 反转字符串中的单词 III(java版)-2024年4月06日

1.题目描述 2.知识点 1)用StringBuilder的方法 实现可变字符串结果 最后返回的时候用.toString的方法 2)在Java中使用StringBuilder的toString()方法时,它会返回StringBuilder对象当前包含的所有字符序列的字符串表示。 在我们的例子中,sb是一个Stri…