Linux网络编程 -ip
Posted 蚍蜉撼树谈何易
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux网络编程 -ip相关的知识,希望对你有一定的参考价值。
目录
ip报头
->4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是4.
->4位头部长度(header length): IP头部的长度是多少个32bit, 也就是 length * 4 的字节数. 4bit表示最大的数字是15, 因此IP头部最大长度是60字节.
->8位服务类型(Type Of Service): 3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0). 4位TOS分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于ssh/telnet这样的应用程序, 最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要.
->16位总长度(total length): IP数据报整体占多少个字节.
->16位标识(id): 唯一的标识主机发送的报文. 如果IP报文在数据链路层被分片了, 那么每一个片里面的这个id都是相同的.
->3位标志字段: 第一位保留(保留的意思是现在不用, 但是还没想好说不定以后要用到). 第二位置为1表示禁止分片, 这时候如果报文长度超过MTU, IP模块就会丢弃报文. 第三位表示"更多分片", 如果分片了的话,最后一个分片置为1, 其他是0. 类似于一个结束标记.
->13位分片偏移(framegament offset): 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是8的整数倍(否则报文就不连续了).
->8位生存时间(Time To Live, TTL): 数据报到达目的地的最大报文跳数. 一般是64. 每次经过一个路由, TTL-= 1, 一直减到0还没到达, 那么就丢弃了. 这个字段主要是用来防止出现路由循环
->8位协议: 表示上层协议的类型
16位头部校验和: 使用CRC进行校验, 来鉴别头部是否损坏.
32位源地址和32位目标地址: 表示发送端和接收端
数据链路层的主要作用是在互连同一种数据链路的节点之间进行包传递。而一旦跨越多种数据链路,就需要借助网络层。网络层可以跨越不同的数据链路,即使是在不同的数据链路上也能实现两端节点之间的数据包传输
如何做到报头与有效载荷的分离?
4位首部长度 和TCP报头中的4位首部长度一样,代表的是IP报头的长度是多少个4字节,4位比特位能够表示的最大数字是15,即IP头部的最大长度是15*4 = 60字节16位总长度 指的是IP数据报整体占多少个字节。用总长度-报头即为有效载荷
TTL(8位生存时间)存在合理性?
如果不存在TTL这个的话,则整个网络中可能会充斥着大量的”流浪者“,游离报文。
路由查找的本质
IP提供了一种能力,可以将数据从A主机跨网络送到B主机
所以说,能力只是决定了将该事情办成的几率大,并不确定一定能完成。要想IP一定将数据从主机A跨网络传送到主机B,它的上层也就是TCP可以控制它,如果传送失败,反复传送 ,直到传送到为止。
IP的可靠性是由TCP保证的,IP本身不保证可靠性。
集线器作用?
集线器(HUB)属于 数据通信系统 中的基础设备,它和 双绞线 等传输介质一样,是 一种不需任何软件支持或只需很少管理软件管理的硬件设备。它被广泛应用到各种场合。 集线器工作在局域网(LAN)环境, 应用于OSI参考模型第一层,因此又被称为物理层 设备。集线器内部采用了电器互联,当维护LAN的环境是逻辑总线或 环型结构 时,完全可以用集线器建立一个物理上的星型或树型网络结构。在这方面,集线器所起的作用相当于多端口的 中继器 。其实,集线器实际上就是中继器的一种,其区别仅在于集线器能够提供更多的端口服务,所以集线器又叫 多口中继器。 HUB按照对输入信号的处理方式上,可以分为无源HUB、有源HUB、智能HUB。
工作过程:集线器的工作过程是非常简单的,它可以这样的简单描述:首先是节点发信号到线路,集线器接收该信号,因信号在电缆传输中有衰减,集线器接收信号后将衰减的信号整形放大,最后集线器将放大的信号广播转发给其他所有端口。
IP分片问题与组装问题
为什么要分片
mtu:最大传送单元,针对于底层网卡、MAC帧所能承受的最大载荷
这里的1500是ip报头+有效载荷<=1500,所以最大ip有效载荷为1480,分片只是在网络层进行分片。因为会交付底层的mac帧
如何分片
将有效载荷拆分为多个数据,每个数据前(有效载荷)都必须加上相应的ip报头。交付给数据链路层。
如何组装
因为数据链路层的最大传输单元为1500个字节,所以当面临大数据交付给上层ip时,ip必须将收到的报文经过组装,组装给一个交给传输层。
如何区分是否分片?
看3位标志位中的第二个标志位是否为0,为0就是分片的,为1就是一个独立的报文。还有可以看13位片偏移,片偏移不为0的就是经过分片的。
如何组装?
通过16位标识确定分片属于哪个报文,同时将13位片偏移进行排序,然后去掉报头组装即可(可以确定中间哪一段丢失)。根据3位标识中最后一位是否为1来确定报文组装是否完毕(确定报文是否组装完毕,同时判断最后一片是否丢失)。
分片丢失怎么办
TCP不关心分片,所以当发送的无论那一片丢失的话,TCP都会将整个数据重新发送。
MTU’概念
1.以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位;
2.最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU
3.如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation);
4.不同的数据链路层标准的MTU是不同的;
MTU对ip影响
分包与和包都在网络层做的。
1.将较大的IP包分成多个小包, 并给每个小包打上标签;
2.每个小包IP协议头的 16位标识(id) 都是相同的;
3.每个小包的IP协议头的3位标志字段中, 第2位置为0, 表示允许分片, 第3位来表示结束标记(当前是否是最后一个小包, 是的话置为1, 否则置为0);
4.到达对端时再将这些小包, 会按顺序重组, 拼装到一起返回给传输层;
5.一旦这些小包中任意一个小包丢失, 接收端的重组就会失败. 但是IP层不会负责重新传输数据,tcp/udp
MTU对udp影响
一旦UDP携带的数据超过1472(1500 - 20(IP首部) - 8(UDP首部)), 那么就会在网络层分成多个IP数据报.
这多个IP数据报有任意一个丢失, 都会引起接收端网络层重组失败. 那么这就意味着, 如果UDP数据报在网络层被分片, 整个数据被丢失的概率就大大增加了.
MTU对tcp影响
1.TCP的一个数据报也不能无限大, 还是受制于MTU. TCP的单个数据报的最大消息长度, 称为MSS(Max Segment Size);
2.TCP在建立连接的过程中, 通信双方会进行MSS协商.
3.最理想的情况下, MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于数据链路层的MTU).
4.双方在发送SYN的时候会在TCP头部写入自己能支持的MSS值.
5.然后双方得知对方的MSS值之后, 选择较小的作为最终MSS.
6.MSS的值就是在TCP首部的40字节变长选项中(kind=2);
网段划分—
同一局域网的网络号是一定相同的。但主机号一定不同。
不同局域网网络号一定是不同的,但主机号可能相同。
子网掩码–CIDR技术
目的:通过子网掩码与ip地址按位与得到网络号,确定子网的划分范围。
路由器功能
1.路由转发功能
2.分配ip的功能 --DHCP技术
特殊ip
将IP地址中的主机地址全部设为0, 就成为了网络号, 代表这个局域网;
将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包;
127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
私网IP与公网IP
公网ip:指的是在全世界范围内能唯一标识这台主机的ip地址。公网IP一般是网络运营商分配的。包括固定的和自动分配的。
内网ip:在局域网中根据自动分配ip的。所以内网的ip在当前局域网中是唯一的,但在所以的网络的ip中不是唯一的。
NAT(Network Address Translator)技术
NAT(Network Address Translator)技术是网络地址转换,它实现内网的IP地址与公网的地址之间的相互转换,将大量的内网IP地址转换为一个或少量的公网IP地址,减少对公网IP地址的占用。
建立请求
源IP:192.168.1.200
目的IP:122.77.241.3
到达家用路由器
源IP:192.168.1.1
目的IP: 122.77.241.3
到达运营商路由器
源IP:10.1.1.1
目的IP:122.77.241.3
服务器收到后,响应请求
源IP:122.77.241.3
目的IP:10.1.1.1
但是知道目的IP为10.1.1.1,怎么将响应送还到192.168.1.200呢?
在NAT路由器内部,有一张自动生成的,用于地址转换的表,当192.168.1.200第一次向122.77.241.3发送数据时就会产生映射关系
一个路由器可以配置两个IP,一个是WAN口IP,一个是LAN口IP
不同的路由器,子网IP都是一样的(通常都是192.168.1.1),子网内的主机IP地址不能重复,但是子网间的IP地址就可以重复了
在发送请求:
1.所有的请求必须经过运营商的中转
2.所有的请求都必须经过不断的NAT地址转化才能发到公网当中
解决了发,但是怎么收呢?
在发送的过程中会建立一个路由表,其经过路由器替换后会建立NAT转换表,保存的是原来发送方的目的ip和源ip和相应的端口,另一个路由表标识了新建立的的目的ip和源ip和端口,它们两个互为key值,此时回来的话,只需要对比两个路由表间的映射关系,便可以找到目标网络,然后通过第一次转发后保存的路由表找到位于目标网络中的唯一一个ip,(局域网中主机ip)找到该主机,此时再通过对应的端口号找到该主机上的进程。
路由
发送数据包时所使用的地址是网络层的地址,即IP地址。然而仅仅有IP地址还不足以实现将数据包发送到对端目标地址,在数据发送过程中还需要类似于“指明路由器或主机”的信息,以便真正发往目标地址。保存这种信息的就是路由控制表(Routing Table)。实现IP通信的主机和路由器都必须持有一张这样的表。它们也正是在这个表格的基础上才得以进行数据包发送的。
路由表的Destinaion是目的网络地址
Genmask是子网掩码
Gateway是下一跳地址
Iface是发送接口
Flags中的 U标志表示此条目有效 G表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经过路由器转发。
这台主机上右两个网络接口,一个网络接口连到192.168.10.0/24,另一个网络接口连到192.168.56.0/24网络
转发过程中,如果要发送的数据包的地址是192.168.56.3
跟第一行的子网掩码做与运算得到192.168.56.0,与目的网络地址不符
跟第二行的子网掩码做与运算得到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去
由于192.168.56.0/24正是与eth1接口直接相连接的网络,因此可以直接发到目标主机,不需要经过路由转发
转发过程中,如果要发送的数据包的地址是202.10.1.2
依次和路由表的前几项进行对比,发现都不匹配
发往192.168.10.1默认的路由器
由192.168.10.1根据它的路由表选择下一跳的地址
以上是关于Linux网络编程 -ip的主要内容,如果未能解决你的问题,请参考以下文章
(46)LINUX应用编程和网络编程之一Linux应用编程框架
理解 Linux 网络栈 (Linux networking stack):Linux 网络协议栈简单总结