【套接字】网络基础 - OSI模型、NAT墙、字节序问题

1. IP

IPv4

(1)IPv4是一个32位的整数,一共4个字节,分成4份,用.符号隔开,每份1个字节
(2)每份8位,最大就是2的8次方,因此为0~255的数
(3)IPv4地址最多有2的32次方个,因此早就分配完了

IPv6

(1)IPv6是一个128位的整数,一共16个字节,分为8份,用:符号隔开,每份2个字节
(2)每份16位,使用16进制表示,每个字节是从00~ff的数
(3)IPv6地址最多有2的128次方个,不可能分配的完

2. 端口

(1)端口的作用就是定位到主机的具体进程。
(2)端口是一个unsigned short类型的数,是一个16位的数,范围是0~65535。其中0~1023的端口称为公认端口/系统端口,是默认的系统保留的端口号,比如80为HTTP的保留端口,也存在某些应用的专属端口,端口号1024~49151为用户端口,由IANA负责注册,任何协议和开发者都可以向IANA申请注册,比如3306为MySQL的默认端口,而49152~65535的端口我们可以随意更改,称为动态端口,任何进程使用它们都是公平的。
(3)不是所有进程的对应一个端口号,通常是要用于网络通信的进程才会绑定一个端口号,同一时间一个端口号只能绑定一个进程。

3. OSI模型

OSI模型是ISO组织开发出的一个公有协议栈,在游戏开发中通常只关心以下5层模型

在这里插入图片描述

3.1 Data Link(链路层)

链路层与物理层关系紧密,通常一个物理介质对应多个不同的链路层协议,其中以太网(Ethernet)是一组基于以太网蓝皮书的协议族,用于各种各样的物理介质中。以太网引入了介质访问控制地址(MAC地址),该地址是一个48比特的数字,即是一个6个字节的MAC地址,MAC地址烧到了每一个网卡当中,是真正的唯一硬件标识符,前24位为网卡生产商的唯一代码,后24位为生产出来的硬件的唯一标识符。

每个数据包的格式如下:

在这里插入图片描述

前导序列帧开始标志都是一样的,是一个十六进制的值0x55 0x55 0x55 0x55 0xx55 0x55 0x55 0xD5,网卡将其剥离出来,剩下的传入以太网模块。
目的地址是接收方的MAC地址,其中FF:FF:FF:FF:FF:FF为广播地址。
帧长度/类型域当其值小于1500时,表示帧长度,大于1536时,表示协议类型,同时最大传输单元为1500字节
数据存储在payload中,是一个帧内封装的报文数据。
帧检验序列检查传输中的数据损坏和帧丢失,但注意帧的传输是不可靠的,链路层并不会做任何操作来确认帧是否到达或重新发送。

同时链路层存在很多弊端:
(1)链路层只依靠每个网卡的MAC地址,如果网卡坏了,那么会缺失灵活性。
(2)链路层在一个网络上运行,如果想要在办公室划分一个安全区域(局域网),链路层无法做到。
(3)链路层没有从一个协议到另一个协议的通信方法。
因此需要更高层的模型的抽象来解决对应问题

3.2 Network(网络层)

Ⅰ IPv4数据包

IPv4数据包的结构如下:

在这里插入图片描述

版本号:长度为4位,,标识目前采用的IP协议的版本。
IP包头长度:长度为4位,描述包头到哪里结束,封装的数据从哪里开始,其值为0~15,以32位(4个字节)为一个单位,因为所有数据包头都是以4字节为整数倍的,最大表示60个字节。
服务类型:占8位,用于标识服务识别的各种目的。
IP包总长:占16位,最大能表示2的16次方,也就是0~25535,以一个字节为单位。IP数据包头至少占20个字节,因此数据部分的最大长度为65515字节。
片标识符:占16位,同一组分片的所有片都设置一个相同的片标识符。
片标记:占3位,片标记如果是MF(0x4),表示还有更多的分片数据包,如果是DF(0x2),表示这个数据包不能分片。
片偏移:占13位,最大为2的16次方,除以2的13次方,所得值为8,因此是以8个字节为单位的偏移量。
生存时间(TTL):占8位,用于限制数据包转发的次数,每经过一个路由器,TTL将会减1,当TTL为0时,路由器会将其抛弃。
协议:占8位,解释数据内容所使用的协议。
头部检验和:占16位,用于IPv4头部正确性的检验,仅仅针对头部数据的检验,不对数据做完整性检验。
源地址:长度为32位,数据包发送方的IP地址。
目标地址:长度为32位,数据包接收方的IP地址。

Ⅱ 直接路由

理论上,一台主机拥有一个IP和一个MAC,网络层封装好数据包的源IP地址和目标IP地址后,将数据包交给链路层时,链路层是无法将IP解析成MAC的,因此ARP(地址解析协议)诞生了,转换时通过查询IP地址到MAC的映射表,如果不在表内,ARP模块将向链路层所有可到达的主机发送ARP报文。

在这里插入图片描述

其中操作类型:占用16位,取值是1或2,1为请求,2为响应。
如果操作类型为请求,那么目标硬件地址将会被接收方忽略。

比如一个主机想要请求另一个主机的MAC地址,那么需要准备一个ARP报文,将操作类型改为1,同时将该ARP报文封装成帧,同时以广播地址的形式FF:FF:FF:FF:FF:FF发送出去,目标IP对应的主机收到后,回一个ARP报文,操作类型为响应,最后更新映射表即可。
注意:ARP以广播的形式发出后,即使无关,也会把所有其他的映射表中的发出者项进行更新;同时如果有恶意的主机发出ARP报文,会存在安全隐患。

Ⅲ 子网掩码

在这里插入图片描述

子网掩码以按位与的方式,规定了在该子网掩码下的一群主机,比如18.19.100.0/24表示18.1.100.XXX的一群主机。

每个IPv4模块中都包含一个路由表,下图为路由器表的实际内容。

在这里插入图片描述
在这里插入图片描述

目标子网:会和目标地址进行掩码的匹配,而0.0.0.0/0为默认的值,如果都不匹配,将会执行该行。
网关:不是直接路由能到达的,指明当前子网通过链路层发送的下一台IP地址,如果为空,即直接路由就可到达。
IPS(互联网服务商):如果要和其他网关通信,发送给0.0.0.0/0将转发给IPS的网关,再转发给其他服务商的网关。

注意:
(1)127.0.0.1称为回路地址/本地地址,如果发送数据包给回路地址,那么会直接处理收到数据包,并传给上一层。
(2)255.255.255.255受限的广播地址,不被路由器所发送,会打包成链路层帧,发送MAC的广播地址FF:FF:FF:FF:FF:FF
(3)在路由器之间不断转发,因此网络层也是不可靠的

Ⅳ 分片

数据链路层的帧最大封装数据为1500字节,而网络层的最大传输单元为655355字节,那么需要分片来将IP数据包封装成帧。
IP数据包通过片标识符、片偏移和片标记拆分为多个IP数据包被发送出去,在转发的时候,接收方的IP模块将创建一个64KB的缓冲区,以发送方的IP和片标识来标记缓冲区,最终所有数据都到达了会将其重建,发给上层做处理。

在这里插入图片描述

注意:游戏开发中,会尽可能将数据包的值限制在1300以内,越大越好,因为IP头数据占用的比例会越小,这样你浪费的带宽会越小。

3.3 Transport(传输层)

网络层负责两个主机之间的通信,而传输层负责这些主机上单独进程之间的通信,即端口之间的通信。

Ⅰ UDP(用户数据报协议)

UDP协议包含一个64位(8字节)的报头,UDP不会保证数据顺序传输和准确到达。

在这里插入图片描述

源端口号:占16位,发送方的端口
目标端口号:占16位,接收方的端口
数据报长度:占16位,是指包含UDP包头和数据的总长度
检验和:占16位

Ⅱ TCP(传输控制协议)

TCP是在两台主机之间创建持久性的连接,提供可靠的数据流传输。因此TCP具有面向连接、安全、流式传输的特点

在这里插入图片描述

序列号:占32位,是一个单调递增的数字,通过TCP传输的每个字节都有一个唯一标识的序列号。
确认号:占32位,包含发送方期望收到的下一个字节的序列号,通常会比序列号多1,若序列号低于确认号,会进行实际的确认。
接收窗口:占16位,表示剩余缓冲空间的最大容量,为避免一直发送,用于流量控制。

Ⅲ 三次握手与四次挥手

三次握手过程
注意:握手时一定是客户端先发向给服务器
1.客户端给服务器发起连接请求
2.服务器同意连接请求回复OK,同时向客户端发起连接请求
3.客户端同意连接请求回复OK

四次挥手过程
注意:挥手时谁先发送都无所谓,以客户端先请求断开为例
1.客户端给服务器发送断开连接的请求
2.服务器同意了断开连接的请求,并回复了OK
3.服务器再次发送自己想断开连接的请求给客户端
4.客户端同意断开连接,并回复OK

Ⅳ TCP状态变量

SND.NXT:表示下一个报文段发送的序列号,发送后会自增发送的长度,因为TCP是连续的
RCV.NXT:主机期望收到的下一个报文段的序列号
SND.UNA:发送的最早未确认的报文段序列号
Seq:发送的序列号,即SND.NXT值
Ack:响应的序列号,即RCV.NXT值
SYN:连接请求标志
ACK:响应标志,确认字符

在这里插入图片描述

TCP使用接收窗口大小来进行流量控制
如果发送的请求大小大于缓冲区的接收窗口大小的话,就会停止发送,直至返回可发送的接收窗口大小。
Window:接收窗口大小

在这里插入图片描述

3.4 Application(应用层)

应用层存在与应用的网络模块内,通过调用应用层的协议实现网络链接。

DNS

DNS是一个域名系统,当我们输入www.google.com的时候,我们向名称服务器发送一个DNS查询,里面存储了域名和IP地址的映射。
注意:
(1)名称服务器不止一个,每天有成千上万个名称服务器,通常会指向区域的权威服务器。
(2)第一次查询会在名称服务器上查询,而之后这个结果会被缓存。
(3)查询和响应通常使用UDP协议,使用端口号53。

4. NAT(网络地址转换)

现在的路由器是能对地址进行转换的,通过配置NAT网络,给每台主机分配一个本地可路由的IP,相当于这个**本地的局域网(LAN)通过广域网(WAN)**向外进行链接,在IANA中保留的本地IP地址如下:

在这里插入图片描述

在这里插入图片描述

"NAT墙"有一个NAT表,通过重写IP地址和端口号的方式,使在NAT墙后的主机能与公网的主机建立通信,在表中记录了原始IP地址、端口号和映射关系。
NAT分为全锥形,受限锥形,端口受限锥形,对称形,全锥形什么都不限制打通后任何外界的都能从"洞"访问进来;受限锥形限制了IP,相当于同一IP的任意端口都能进来;端口受限锥形是同一主机的同一端口能进来;对称形即一个端口对应一个主机,相当于是点对点的唯一连接。
如果两个躲在NAT墙后面的主机通信,就需要对其进行UDP打洞借助第三方的STUN,STUN是UDP对NAT的简单穿越方式,首先判断NAT类型,然后进行对应类型的打洞操作即可,步骤如下:
(1)主机向STUN服务器发送UDP信息,如果在NAT后,相当于NAT更改过的给STUN发送信息,接着STUN把收到的IP和端口号返回给主机(或者更改IP和端口号,检验受限锥形或端口受限锥形),主机收到后跟自己原有的进行匹配,即可判断自己的类型
(2)如果只有一方躲在NAT墙后或NAT墙的类型不是对称形,STUN调用TURN让躲在NAT墙后的主机主动发信息,以此打通NAT洞;若双方的NAT墙类型是对称型,STUN只好调用TURN当一个第三方服务器,用TURN来建立收发消息的工作。

在这里插入图片描述

5. 字节序问题

字节序:大于一个字节的数据在内存中的存储顺序,注意单字节是没有字节序问题的。
数据通过OSI模型的封装,最终存到内存中,通过网络发送给另一台主机的内存中,如果内存中的排列方式不一致,将会产生大小端问题。
大端模式(网络字节序):称为高位字节优先,即数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。
小端模式(主机字节序):称为低位字节优先,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
比如:一个数0x12345678
在主机中/小端:0x78 56 34 12
在网络中/大端:0x12 34 56 78

大小端转换函数

#include <arpa/inet.h>
/** 函数作用:主机的小端字符串转化为网络的大端整型数
 * @Param af:IP类型,AF_INET为IPv4,AF_INET6为IPv6
 * @Param src:要转换的小端IP字符串存储的地址
 * @Param dst:整形变量的指针,存储转换之后的整形数
 * @Ret:函数调用成功返回1;af参数有问题返回-1;src参数有问题发返回0
 */
int inet_pton(int af, const char *src, void *dst); 
#include <arpa/inet.h>
/** 函数作用:网络的大端整型数转化为主机的小端字符串
 * @Param af:IP类型,AF_INET为IPv4,AF_INET6为IPv6
 * @Param src:要转换的大端IP整型数存储的地址
 * @Param dst:字符串变量的指针,存储转换之后的字符串
 * @Param size:计算的dst对应内存的大小
 * @Ret:函数调用成功返回非空指针,该指针指向dst;调用失败返回空指针
 */      
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

6. 常见概念简述

Ping/RTT(网络延时):指一个数据包从用户的设备发送到测速点,然后再立即从测速点返回用户设备的来回时间,以毫秒ms计算。
网络抖动:指最大延时与最小延时的时间差,主要用来评价网络的稳定性,抖动越小,网络越稳定。
丢包率:指发送数据中所丢失数据包数量占所发送数据包的比率,以报文为单位进行计算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值