Linux C高级编程——网络编程之以太网(2)
Linux网络编程——以太网
宗旨:技术的学习是有限的,分享的精神是无限的。
1、以太网帧格式
源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的。用ifconfig命令查看,“ 硬件地址 00:0c:29:cf:7e:1a ” 。协议字段有三种值,分别相应IP、 ARP、 RARP。帧末尾是CRC校验码。
ARP和RARP数据包的长度不够46字节。要在后面补填充位。
最大值1500称为以太网的最大传输单元( MTU),不同的网络类型有不同的MTU,假设一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了。则须要对数据包进行分片( fragmentation)。
ifconfig查看“ MTU:1500”。
MTU这个概念指数据帧中有效载荷的最大长度,不包含帧首部的长度。
2、数据报格式
在网络通讯时,源主机的应用程序知道目的主机的IP地址和port号。却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,假设接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址。 ARP协议就起到这个作用。源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”,并将这个请求广播到本地网段(以太网帧首部的硬件地址填FF:FF:FF:FF:FF:FF表示广播),目的主机接收到广播的ARP请求,发现当中的IP地址与本机相符。则发送一个ARP应答数据包给源主机。将自己的硬件地址填写在应答包中。
每台主机都维护一个ARP缓存表,能够用arp -a命令查看。缓存表中的表项有过期时间(一般为20分钟),假设20分钟内没有再次使用某个表项,则该表项失效,下次还要发ARP请求来获得目的主机的硬件地址。
ARP数据报格式:
注意到源MAC地址、目的MAC地址在以太网首部和ARP请求中各出现一次。对于链路层为以太网的情况是多余的,但假设链路层是其他类型的网络则有可能是必要的。硬件类型指链路层网络类型。1为以太网,协议类型指要转换的地址类型,0x0800为IP地址,后面两个地址长度对于以太网地址和IP地址分别为6和4(字节)。op字段为1表示ARP请求,op字段为2表示ARP应答。
比如请求帧:
以太网首部( 14字节)
0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06
ARP帧( 28字节)
0000: 00 01
0010: 08 00 06 04 00 01 00 05 5d 61 58 a8 c0 a8 00 37
0020: 00 00 00 00 00 00 c0 a8 00 0218
填充位( 字节)
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太网首部:目的主机採用广播地址,源主机的MAC地址是00:05:5d:61:58:a8。上层协议类型0x0806表示ARP。
ARP帧:硬件类型0x0001表示以太网。协议类型0x0800表示IP协议,硬件地址(MAC地址)长度为6,协议地址(IP地址)长度为4,op为0x0001表示请求目的主机的MAC地址。源主机MAC地址为00:05:5d:61:58:a8,源主机IP地址为c0 a8 00 37(192.168.0.55),目的主机MAC地址全0待填写。目的主机IP地址为c0 a8 00 02(192.168.0.2)。
因为以太网规定最小数据长度为46字节。 ARP帧长度仅仅有28字节。因此有18字节填充位,填充位的内容未定义,与详细实现相关。
应答帧例如以下:
以太网首部
0000: 00 05 5d 61 58 a8 00 05 5d a1 b8 40 08 06
ARP帧0000: 00 01
0010: 08 00 06 04 00 02 00 05 5d a1 b8 40 c0 a8 00 02
0020: 00 05 5d 61 58 a8 c0 a8 00 37
填充位0020: 00 77 31 d2 50 100030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太网首部:目的主机的MAC地址是00:05:5d:61:58:a8,源主机的MAC地址是00:05:5d:a1:b8:40。上层协议类型0x0806表示ARP。
ARP帧:硬件类型0x0001表示以太网,协议类型0x0800表示IP协议。硬件地址( MAC地址)长度为6,协议地址( IP地址)长度为4,op为0x0002表示应答,源主机MAC地址为00:05:5d:a1:b8:40,源主机IP地址为c0 a8 00 02( 192.168.0.2)。目的主机MAC地址为00:05:5d:61:58:a8。目的主机IP地址为c0 a8 00 37( 192.168.0.55)。
3、数据报格式
IP数据报的首部长度和数据长度都是可变长的。但总是4字节的整数倍。对于IPv4,4位版本号字段是4。4位首部长度的数值是以4字节为单位的。最小值为5。也就是说首部长度最小是4x5=20字节,也就是不带不论什么选项的IP首部,4位能表示的最大值是15,也就是说首部长度最大是60字节。8位TOS字段有3个位用来指定IP数据报的优先级(眼下已经废弃不用),还有4个位表示可选的服务类型(最小延迟、最大呑吐量、最大可靠性、最小成本),另一个位总是0。
总长度是整个数据报(包含IP首部和IP层payload)的字节数。每传一个IP数据报,16位的标识加1,可用于分片和又一次组装数据报。3位标志和13位片偏移用于分片。 TTL(Time to live)是这样用的:源主机为数据包设定一个生存时间,比方64,每过一个路由器就把该值减1。假设减到0就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。协议字段指示上层协议是TCP、UDP、ICMP还是IGMP。然后是校验和,仅仅校验IP首部,数据的校验由更高层协议负责。IPv4的IP地址长度为32位。
4、IP地址
IPv4的IP地址长度为4字节,通常採用点分十进制表示法(dotted decimal representation)比如0xc0a80002表示为192.168.0.2。 Internet被各种路由器和网关设备分隔成非常多网段。为了标识不同的网段,须要把32位的IP地址划分成网络号和主机号两部分。网络号同样的各主机位于同一网段,相互间能够直接通信,网络号不同的主机之间通信则须要通过路由器转发。
A类 0.0.0.0到127.255.255.255
B类 128.0.0.0到191.255.255.255
C类 192.0.0.0到223.255.255.255
D类 224.0.0.0到239.255.255.255
E类 240.0.0.0到247.255.255.255
一个A类网络可容纳的地址数量最大,一个B类网络的地址数量是65536。一个C类网络的地址数量是256。 D类地址用作多播地址。 E类地址保留未用。
网络号和主机号的划分须要用一个额外的子网掩码(subnet mask)来表示,而不能由IP地址本身的数值决定,也就是说,网络号和主机号的划分与这个IP地址是A类、 B类还是C类无关,因此称为Classless的。
这样,多个子网就能够汇总(summarize)成一个Internet上的网络,比如,有8个网站都申请了C类网络,本来网络号是24位的,可是这8个网站通过同一个ISP(Internet serviceprovider)连到Internet上,它们网络号的高21位是同样的,仅仅有低三位不同,这8个网站就能够汇总,在Internet上仅仅须要一个路由表项,数据包通过Internet上的路由器到达ISP,然后在ISP这边再通过次级的路由器选路到某个网站。
比如:子网1
子网2:
到全1就是子网的地址范围。IP地址和子网掩码另一种更简洁的表示方法。比如140.252.20.68/24。表示IP地址为140.252.20.68。子网掩码的高24位是1。也就是255.255.255.0。
假设一个组织内部组建局域网, IP地址仅仅用于局域网内的通信,而不直接连到Internet上,理论上使用随意的IP地址都能够。可是RFC 1918规定了用于组建局域网的私有IP地址,这些地址不会出如今Internet上,例如以下表所看到的。
10.*,前8位是网络号,共16,777,216个地址
172.16.*到172.31.*。前12位是网络号。共1,048,576个地址
192.168.*,前16位是网络号。共65,536个地址
127.*的IP地址用于本机环回(loop back)測试,一般是127.0.0.1。loopback是系统中一种特殊的网络设备。假设发送数据包的目的地址是环回地址,或者与本机其他网络设备的IP地址同样,则数据包不会发送到网络介质上,而是通过环回设备再发回给上层协议和应用程序。主要用于測试。
Linux C高级编程——网络编程之以太网(2)的更多相关文章
- python高级之网络编程
python高级之网络编程 本节内容 网络通信概念 socket编程 socket模块一些方法 聊天socket实现 远程执行命令及上传文件 socketserver及其源码分析 1.网络通信概念 说 ...
- 第六篇:python高级之网络编程
python高级之网络编程 python高级之网络编程 本节内容 网络通信概念 socket编程 socket模块一些方法 聊天socket实现 远程执行命令及上传文件 socketserver及 ...
- Linux下高并发网络编程
Linux下高并发网络编程 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时, 最高的并发数量都要受到系统对用户单一进程同时可打 ...
- Linux C高级编程——网络编程基础(1)
Linux高级编程--BSD socket的网络编程 宗旨:技术的学习是有限的,分享的精神是无限的. 一网络通信基础 TCP/IP协议簇基础:之所以称TCP/IP是一个协议簇,是由于TCP/IP包括T ...
- Linux IO模型和网络编程模型
术语概念描述: IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者. 阻塞和非阻塞,是函数/方法的实现方式,即在数据就绪之前是立刻返回还是等待. 以文件IO为例,一个IO读过程是文件 ...
- linux服务器开发三(网络编程)
网络基础 协议的概念 什么是协议 从应用的角度出发,协议可理解为"规则",是数据传输和数据的解释的规则. 假设,A.B双方欲传输文件.规定: 第一次,传输文件名,接收方接收到文件名 ...
- Java 基础高级2 网络编程
1.协议的概念:通信双方事先约定好的通信规则 2七层网络通信协议:应用成,表示层,会话层,传输层,网络层,数据链路层 3.TCP/IP协议:点对点通信,三层握手,安全有保证 4.UDP协议;广播协议, ...
- linux服务端的网络编程
常见的Linux服务端的开发模型有多进程.多线程和IO复用,即select.poll和epoll三种方式,其中现在广泛使用的IO模型主要epoll,关于该模型的性能相较于select和poll要好不少 ...
- linux网络编程--网络编程的基本函数介绍与使用【转】
本文转载自:http://blog.csdn.net/yusiguyuan/article/details/17538499 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览 ...
随机推荐
- sql查询总结
1.SQL select 语句 SELECT 语句用于从表中选取数据. 结果被存储在一个结果表中(称为结果集). SELECT 列名称 FROM 表名称 实例: SELECT username,pas ...
- 88. Merge Sorted Array【Easy】【双指针-不用额外空间归并两个有序数组】
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: T ...
- HashMap底层数据结构和算法解析
1.Hash Map的数据结构? A:哈希表结构(链表散列:数组+链表)实现,结合数组和链表的优点.当链表长度超过8时,链表转换为红黑树. transient Node<K,V>[] ta ...
- Java工具类-格式化日期
package common; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; p ...
- Keras 训练时出现 CUDA_ERROR_OUT_OF_MEMORY 错误
不用惊慌,再试一次.估计当时GPU内存可分配不足,可手动结束所有python程序后释放相关GPU内存,或者重新运行一次终端
- oracle latch工作原理
latch是一种轻量级用于保护oracle共享内存结构,用户并发操作一致性的串行化锁定机制,如SGA中,各种数据被反复从磁盘读取到内存,又被重新写回到磁盘上,如果有并发用户做相同的事情,oracle必 ...
- [BZOJ5011][JXOI2017]颜色
5011: [Jx2017]颜色 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 84 Solved: 46[Submit][Status][Disc ...
- BZOJ 1123 [POI2008]BLO(Tarjan算法)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1123 [题目大意] Byteotia城市有n个towns,m条双向roads. 每条r ...
- 【manacher】HDU4513-吉哥系列故事——完美队形II
[题目大意] 求最长回文队伍且队伍由中间向两边递减. [思路] 和字符串一样的做法,在递推的时候增加判断条件:a[i-p[i]]<=a[i-p[i]+2]. #include<iostre ...
- 最简单的flask表单登录
from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=['GE ...