TCP的异常处理
进程终止
当我们强制杀死一个进程时,这时的TCP连接是咋样呢?
TCP连接是通过Socket来建立的,Socket本质是进程打开的一个文件,而文件就存在于进程的PCB中的文件描述符表,每次打开一个文件(包括Socket)就会在文件描述符表中添加一项!
每次关闭一个文件就在文件描述符表中删除该项!
如果直接杀死进程,PCB也就没了,文件描述符表自然没了,相当于手动调用了socket.close效果一样!
机器关机
关机机器会先通过操作系统将主机中的所有进程强制结结束也就和上述的进程终止一样,然后再关机
机器掉电/网线断开
机器掉就是电台式机拔掉了电源
操作系统毫无防备,没有对该进程处理后事!
主机B接收方挂了
主机A并不知道该主机已经断电!
一直在等待ACK然后进行超时重传,重传失败几次后就会重新建立连接,最后发现无济于事就断开了连接!
主机A发送方挂了,主机B并不知道是什么原因是A休息了,还是A挂了!
主机B就会时不时发送一个小的报文(不带数据的,只为触发ACK)心跳报探测报文,当A不再放回ACK就认为A出现了问题,就断开连接!
TCP和UDP对比
TCP适用场景
对可靠性有一定要求(日常大部分开发都是基于TCP)
UDP适用场景
对可靠性要求不高,对于效率要求高(机房中主机间通信,分布式系统)
经典面试题
基于UDP如何实现可靠传输(其实在考TCP)
本质就是在应用层协议中基于UDP实现TCP的机制!
确认应答…
UDP是操作系统中已经实现的不能更改,只能更改应用层协议!
网络层(IP协议)
我们知道网络层协议保存着两台设备的IP地址!
所以网络层最重要的协议就是IP协议!
并且博主学习的就是TCP_IP协议栈!
所以这里的IP协议的学习也是重中之重!
我们先来了解一下IP报头格式
IP协议报头格式:
四位版本号
这里是4个bite位,当前IP协议的版本号有IPv4和IPv62个版本,所以版本号只有两个取值,0110和0100分别表示不同的IP协议版本!
4位首部长度
这里的4位首部长度和TCP协议报类似,就是IP协议报头的长度大小!这里的单位是4字节,也就是说当取值1111时表示最大的首部长度是15*4,60字节,这里的IP协议报头中的选项也使得这里的协议报头长度是可变长度的!
8位服务类型(TOS)
这里的8位服务类型,目前只有4位有效!
这四种状态分别吧表示如下含义:
最小延时
最大吞吐量
最高可靠性
最小成本
并且这里的TOS同一时刻只能选择一种状态!
比如:你想要传输过程的最大吞吐量,那就无法保证最高的可靠性,只能4选一!
这里的TOS就相当于切换形态,为了给IP协议报规划一条合适的线路,这里的合适就是你想要选择的一种传输状态!
16位总长度(字节数)
这里的16位总长度表示IP协议报大小最大为64k字节!
而我们知道TCP中的协议报大小可能不止64k!
如果一个超过64k大小的TCP协议报交给传输层IP协议该如何进行分装处理呢?
如果一个报文大小超过了64k,我们可以将IP协议报文进行拆包处理!
将一个TCP协议报拆成多个然后进行传输!
我们知道IP协议报中保存的数据载荷就是一个TCP协议报!
我们就可以把这个TCP协议报拆成多个!
我们就将一个TCP数据报拆成了多个,交个多个IP协议报进行传输!
问题又来了,我们传输过去后,如何确认那几个IP协议报传输的是一个TCP数据报呢?
我们通过下面3个标识位的学习就可以将一个TCP协议数据报进行重新组装!
16位标识位
传输相同的TCP协议报,IP协议报头的16位标识位相同,通过这个16位标识位,我们就可以知道那几个IP协议报是一个TCP协议数据报!
就好比快递一个包裹装不下,那就拆成了2个包裹,当时这两个包裹具有相同的快递单号!
3位标志位
第一位保留(现在IP协议报头还没想好怎么用)
第二位为1,表示禁止分片,就是禁止拆分,如果报文长度超过了MTU(数据链路层中一个以太网数据帧所能承受的最大数据范围),就丢弃该报文!
第三位表示更多分片,就是刚刚当一个协议报拆成多个协议报时,当该IP协议报中的该位为1表示该协议是这个TCP协议数据报拆包后的最后一个IP协议报,否者该位为0!
13位片偏移
是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此,除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)。
简单讲就是这个片偏移可以知道该IP协议报在原来未拆包前报文的位置信息,然后再重新组包时才能将数据组织回去!
8位生存时间(TTL)
(Time To Live):这里的TTL表示一个IP协议报设备之间最大的转发次数,一般设为128或者64,我们知道两个设备之间的通信要经过中间很多台设备的传输过程,一次传输过程就是一次转发经过一个路由器或者交换机TTL就减一!如果TTL的值减小到0,我们就视为该数据永远也传输不到目的IP,就将其丢弃!就好比我们发送的目的IP压根不存在,那无论如何转发传输到到达不了,防止出现路由循环!
8位协议
8位协议的取值就表示这个IP协议数据传输的数据载荷传输层是应用的那种协议!不同传输层的协议类型有不同的取值.
16位首部校验和
16位首部校验这里采用的是CRC算法进行校验,来验证IP头部是否破损!
32位源IP地址
就是发送方的IP地址
32位目的IP地址
接收方的IP地址
我们知道IP地址是由32位比特位构成(这里针对的是IPv4版本)!
我们通常采用点分十进制的格式进行展示!
将32位比特位分成4组每组表示一个字节,然后每组之间用:分割开!
例如:192.168.107.89这就是一个IP地址,但是在计算机内部还是采用2进制格式存储!
选项
这里的选项字段长度不定最多40个字节!
我们介绍完了IP报头格式,我们再来了解一下IP协议报的主要功能!
我们的IP协议在整个网络传输过程中主要完成两件事情!
地址管理
路由选择
地址管理
我们知道IP地址的表示分成4组,每组一个字节!
我们又把这4组数据进行了划分!
前3个字节一般表示网络号,最后一个字节表示主机号!
192.168.107.89
网络号
不同的网络号表示不同的局域网!
主机号
主机号表示该局域网中的设备编号!
我们通过网络号可以找到该局域网,通过主机号可以找到该局域网下的主机设备!
这里的的地址划分是唯一不变的嘛?如果该局域网下的主机设备超过1个字节大小咋整?
这里的地址划分并不唯一,如果该局域网下的主机过多,一个字节一个无法编号!那就需要有新的划分方式,我们这时就要引入子网掩码这个概念!
子网掩码
子网掩码也是32位!通过子网掩码可以将IP地址进行不同的划分方式!
例如:我的IP地址是 192.168.107.89我咱知道我前几位表示网络号,后几位表示主机号呢?
通过这个子网掩码255.255.255.0就可以知道前3个字节表示网络号,最后一个字节表示主机号!
网络号:通过通过1标识(255)
主机号:通过0标识
这里的0和1不能交替,只可能1在前,0在后!
这就是子网掩码地址划分方式
特殊IP地址
根据对地址的划分,我们可以更好的管理IP地址
我们也规定了一些IP地址具有特殊意义!
如果IP主机号全为0,该IP就表示网络号(一个局域网中的设备主机号不能全为1)
如果IP的主机号全为1,该IP就是广播地址,通过这个IP,我们可以对整个局域网中的主机进行消息传输,在该局域网中的设备都可以接收到数据,类似于机房的广播!
如果IP地址以127开头,该IP表示环回IP,就是表示自己的主机,典型的环回IP127.0.0.1
如果IP地址以10开头,192.168开头或者172.16-172.31开头表示该IP地址是一个局域网IP地址,这个IP地址只能由该局域网中的设备访问,其他局域网的设备访问不到这个IP地址!
要求外网IP是唯一的,每个外网IP都会对应到唯一的一台设备,内网IP在一个局域网中是对应到唯一设备的,当时不同局域网中的内网IP可以相同!
我们再思考另一个问题,居然每一台设备都有自己的IP地址,为啥要区分内网IP和外网IP,大家都整一个不同的IP不就好了?
我们知道IP地址范围是32个比特位也就是一个int型数据,而最大的表示范围是4294967295也是是42亿九千万大小!
而如今的世界上的设备远远超过了42亿,如果我们给每一台设备分配一个IP,势必会有设备的IP重复不唯一!
如何解决这个IP分配问题呢?
动态分配IP地址
让每台设备联网的时候分配一个IP地址,设备休息的时候,就不分配IP,然而这个问题并没有从根本上解决这个问题,设备数量一直在增加!
NAT机制
让多台设备共用一个IP(外网IP)
把网络分成了内网(局域网)和外网(广域网)
要求外网IP只能唯一一台设备
同时同一个局域网的设备共用一个外网IP
所以一个外网IP可能表示上千或者上万台设备!
不同的局域网设备可以具有相同的内网IP
这时IP地址分配压力就缓解了!
NAT机制下的重要结论:
有外网IP的设备,可以在互联网中的任何地方都可以访问到!
具有内网IP的设备只能由在这个局域网中的设备访问,其他局域网中的设备访问不到!
例如:
在一个学校就是一个局域网,然后每台设备都有一个内网IP,而这个I只能由在这个学校的局域网中的设备访问!
在不同的局域网下那我们如何将主机A的信息发送给主机B呢?
就比如我们发微信,我们先通过这个内网IP,访问一个共用的外网IP,这里可能是运营商的外网IP,通过运营商的外网IP,我们就可以访问到微信的服务器外网IP,然后将消息发送给主机B!
我们知道同一个局域网下共用一个外网IP,那如果该局域网下的多台设备下的客户端程序系统分配绑定相同的端口号咋整?
我们把具有外网IP的路由器设备叫做NAT路由!
通过NAT路由器可以将两个设备的内网IP和端口号记录下来,然后通过某种映射关系,映射新的端口号,然后消息再传回时,根据开始的映射关系将信息返回不同的设备!
IPv6
虽然NAT机制目前解决了地址分配的情况,但是这并不是长远之计!毕竟我们IP设计的初衷就是一台设备分配一个IP地址,所以IPv6从根本上解决了这个问题!
IPv6版本不同于之前的IPv4版本IP地址只有32位比特位!
IPv6版本的IP地址升级具有128位的IP地址!也就是可以保存16位字节大小的数据!直接在IPv4版本42亿9千万的范指数加了个4,就是4个42亿9千万相乘,可想而知范围之大,号称可以将地球上的一粒沙子都编号IP地址!
但是IPv6和IPv4设备并不兼容,需要更改新的设备才能支持IPv6,国家在大力推行IPv6升级!
路由选择
我们知道网络层在网络传输中就相当于快递公司承担着规划路线的作用!我们要规划好合适的线路将该IP地址主机发送的信息传输到另一个IP地址的主机!
如何规划好线路呢?
我们的协议报头中已经保存了发送方和接收方的主机IP,但是我们要选择一条合适的线路,将信息发送过去!
而我们知道网络通信需要经过很多的路由设备,而网络环境复杂,如何选择一条线路到达目的IP地址十分重要!
路由器设备如果知道这个IP地址就可以直接发送过去!
就相当于你要去一个地方,如果你认识路就可以直接过去,如果你不认识路的话只知道大致的方向,那你只能到达一个地方通过问路的方式,继续接下来的前行!
这里的路由器也会通过这种询问的方式,先将数据发送给大致方向的路由器,然后由接下来的路由机继续发送,直到有路由器认识这个IP然后到达这个IP有很多条路线,这时IP协议就会选择合适的线路,这就是路由选择!
路由器如何认识IP呢?
路由器内部维护了一个数据结构路由表
路由表保存了一些网段信息(网络号)目的IP就是通过这些网段信息进行匹配以及每个网段信息对应的网络接口(也就是路由器里面具体的端口),路由器通过相邻的路由设设备保存的路由表信息扩展自己的路由表信息!
数据链路层
数据链路层比较偏底层,我们就大致了解一下!
通过以太网数据帧协议了解数据链路层
以太网数据帧格式:
目的地址
源地址
这里的地址和IP地址不同,称为mac地址(物理地址),每一个设备都有唯一的物理地址(每个网卡都是唯一),这里指的是网卡的物理地址!并且这里的地址范围是6字节所以不存在地址分配问题,保证了每一台设备的物理地址唯一!
这就是博主设备的物理地址, 80-30-49-71-A0-4F可以看到mac地址有6位每位是一个字节!
这里需要注意区分,这里的mac地址是在数据链路层下使用,而IP地址是在网络层下使用,具有不同的功能和作用不要混淆了!
我们知道数据链路层中的目的地址和源地址随着数据的传输时不断改变的!只是记录当前时刻相邻的设备地址!而IP协议报中的始终不变,一直保存着源IP和目的IP
还有这里每个设备的mac地址是在设备出厂时就固定的!
帧协议类型字段
这里的帧协议类型字段有3种取值对应着IP,ARP,RARP.
CRC
这里是帧位的CRC校验码,校验数据是否丢失!
MTU
MTU指的是一个以太网数据帧可以承受的最大数据范围!
MTU的取值取决于2个因数
硬件设备本身,因为传输链路中不同的设备硬件是不同的!
TCP/IP报头长度,因为我们知道TCP和IP的报头长度是变长的,如果TCP和IP的报头长度越长,那MTU也就需要相应减小!
MTU对IP的影响
由于MTU范围大小的限制,使得对网络层IP协议也有所制约,之前所说的IP协议数据报拆包大部分情况下是针对这里数据链路层数据传输的限制,通过MTU,IP协议报也能更好的对数据报进行拆包!
就好比上图,发送快递的过程,当达到一个包裹的最大重量,就需要分成多个包裹进行邮寄!这里的IP也一样,当得知数据链路层的MTU可以承受的最大数据范围,就会将IP协议报数据进行拆包!
MSS
TCP的一个数据报也不能无限大,还是受制于MTU。TCP的单个数据报的最大消息长度,称为MSS(Max Segment Size);
TCP在建立连接的过程中,通信双方会进行MSS协商。
最理想的情况下,MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于数据链路层的MTU)。
双方在发送SYN的时候会在TCP头部写入自己能支持的MSS值。
然后双方得知对方的MSS值之后,选择较小的作为最终MSS。
MSS的值就是在TCP首部的40字节变长选项中(kind=2);
通俗点讲就是这里的MSS,TCP在IP不分包的情况下最大的数据载荷量!
我们连接时双方互通MSS这个值,就可以知道数据链路层在IP协议数据报不分包的情况下可以承受最大的数据载荷量,从而告诉TCP协议传输数据时,数据报按照这个范围打包数据,在接下了的传输过程就避免了拆包,组装的过程,从而提高了传输速率!
ARP
这里的ARP并不是用来传输数据的,而是起到一个辅助传输的效果!
ARP保存IP地址和mac物理地址的映射关系!当我们路由器在转发数据时,首先拿到的是一个IP地址,而我我们需要转发给另一个路由设备,而路由设备的地址是mac地址,这时ARP就可以在以太网数据帧进行封装时,通过ARP协议保存的映射关系,设置源地址和目的地址的值!
ARP协议保存的映射关系从何而来?
当设备启动时,就会向局域网中,广播ARP报文,每个设备接收到后,就会给出一个应答,应答中就包含了自己的IP地址和mac地址,发起广播方就可以通过收集到的映射关系,建立一个映射表!
TCP_IP协议栈还有许多内容等待我们去学习去了解!
加油!