[转]车小胖谈网络(基础篇):同一网段的主机如何通信

http://blog.sina.com.cn/s/blog_1533e35800102wyqd.html

http://blog.sina.com.cn/s/blog_1533e35800102wyqd.html

http://blog.sina.com.cn/s/blog_1533e35800102wyqd.html

最近读者反映文章还要普及一下基础知识,比如专业术语,比如网络包是如何从一台电脑发送出去,网络包如何到达目的地,又如何从目的地网卡接收到,再传输到应用程序。如果把专业术语单独拎出来,没有上下文,同学们一定会觉得很突兀、也很枯燥,所以我还是喜欢讲一个例子,在这个例子中用到的专业术语一一解释,今天我们来讲同一网段的两台电脑如何ping通对方,那第一个问题就来了。


Ping是什么?

操作系统里的一种小程序,可以用来检测两台主机的连通性,如果可以ping通,表示网络可达,否则,网络不可达,网络出故障,需要排错了。先来看一个例子,在主机10.0.0.2上ping主机10.0.0.3,从第一个图可以看出可以ping 通,发出4个echo request,返回对应的4个echo reply;第二个图可以看出全部的8个ping报文,第三个图可以看到具体的ping报文的怎么构成的。


车小胖谈网络:子网与子网掩码

车小胖谈网络:子网与子网掩码


车小胖谈网络:子网与子网掩码


同学们一定很好奇,ping 是如何生成这些ICMP报文的,那下一个问题又来了;


什么是ICMP?

Internet Control Message Protocol,如名字所暗示,这是一个网络控制协议,当网络发生一些或大或小的问题,通过该协议可以告知通信的发起方,比如,当一个IP包太大,比如1500字节,到达一个路由器的接口,接口最大传输单元MTU=1476字节,由于IP包1500>MTU1476,这个IP包必须分成两片才可以从接口发送出去,问题来了,IP包里有一个标志位DF=1,不熟悉这个标志位可以看我的文章:IP协议,意思是这个IP包不能分片,IP包的发起方意思很明显,要么完整给我转发,要么丢,就是不能分片!那路由器只有无奈地丢弃这个IP包,如果没有消息告知这个IP发起者,会发生什么?IP包都被默默丢弃了,而IP包发起方并不知道,还以为数据已经到达了目的地,其实都被丢了,这就是流量黑洞,所以需要一种消息机制告知IP包的发起者,这个消息就是用ICMP来发送的,那发送什么样的消息呢?


ICMP协议里有type字段,还有code字段,发送type=3,code=4,MTU=1476的消息就可以了,当这个ICMP消息到达IP包的发起者,发起者知道原来是IP太大了,那最大可以发送多大的呢?消息里有,那就MTU=1476,于是IP包的发起方只要发送小于等于1476字节的就可以了。


好了,那我们继续我们的主题,ping的ICMP报文是如何生成的,这个是软件工程师最擅长的领域,因为这更像编程,好在车小胖做过七年的软件工程师,操纵Motorola MPC 860芯片,各种物理寄存器、BD表、发送缓存、接收缓存,还写过网卡驱动程序,写过二层HDLC协议,还写过更高一些的如DHCP、PPPoE等协议,所以应该能够给一个大体的框架,步骤如下:

1.  ping 10.0.0.3这条命令敲完回车,ping程序会调用一个发送函数,类似icmp_send(10.0.0.3,...),这种函数我们统称为Application ProgramInterface,简称API,这是操作系统提供的一种函数集合,准确地说是TCP/IP协议栈提供的函数集合,目的是什么呢?用来操作TCP/IP协议栈来发送和接收数据。比如Apple IPhone iOS也提供了很多API,各种APP通过这些API可以操纵手机的相机、喇叭、声音等可以编程,呈现出五彩缤纷的花花界面。好,回到正题,icmp_send(10.0.0.3,…),括号里的是传入参数,省略号表示这些可以是缺省参数,比如长度是length=32字节,发送次数count=4,DF=0,超时timeout=2 秒,如果你想发1500字节的数据,你只要敲以下命令:ping 10.0.0.3 -l 1500


那下面这条命令什么意思?

ping 10.0.0.3 -c 100 -f -l 1500

-c  count

-f  force

-l length

意思是发送100次、长度为1500字节、且不能分片ICMP Echo request。

2. icmp_send(10.0.0.3,…)到达TCP/IP协议栈,栈查找自己的路由表,路由表是什么?下图可以看出主机上路由表大概是什么样子的,为什么要查找路由表?通过查找路由表可以知道该把这个ICMP消息从哪个接口发送出去,那怎么查找?

最长匹配!把10.0.0.3和路由表里的每一个表相进行匹配,匹配长度最长的胜出,在这张路由表里最长的匹配就是第二条路由:10.0.0.0 255.255.255.0 Wi-Fi,栈知道这是和自己在一个网段10.0.0.0/24的主机,可以通过Wi-Fi接口到达,于是发送ARP来解析10.0.0.3的硬件地址,也称为MAC地址,那ARP又是什么呢,还有什么叫同一网段?




什么是同一网段?

比如一个地址,10.0.0.3/24,也可以写成10.0.0.3 255.255.255.0,子网掩码是24位即255.255.255.0,10.0.0.3
和255.255.255.0“按位与”操作得到网段地址,即10.0.0.0 ,剩下的3为主机地址,操作如下:

IP地址10.0.0.3 的二进制:

00001010.00000000.00000000.00000011

子网掩码255.255.255.0的二进制:

11111111.11111111.11111111.00000000

按位与得到的网段地址:

00001010.00000000.00000000.00000000

换算成十进制就是:

10.0.0.0

所谓按位与运算,就是每一位比对,如果都是1得到的结果是1,否则为0。

那10.0.0.2 和10.0.0.3就属于同一网段,同一网段意味着在一个广播域里,ARP就是工作在广播模式下,那ARP又做些什么呢?



什么是ARP?

Address Resolution Protocol,简称为ARP,用来解析IP地址所对应主机的硬件地址,即网卡地址,我们也统称MAC地址,MAC,Media Access Control的缩写,于是栈发了一个ARP请求,地址10.0.0.3是谁的?吭一声,对应图中的第一个包,因为这是一个广播包,所以这个网段的所有主机都可以接收到,于是10.0.0.3就吭了一声,对应图中得第二个包,于是我们就知道了10.0.0.3的MAC地址为:00:30:67:1b:ec:a5



到这里栈有了所有的信息,包括二层以太网目的地址、三层IP目的地址,打包成一个ICMP包发送给网卡,怎么发?当然也是调用网卡驱动程序API,各位同学又看到了API,没错!下层提供给它上层的服务是通过API来实现的,这里相当于调用类似ethernet_send()接口函数,于是ICMP到达网卡。


3. 网卡计算整个以太网帧的校验和,四个字节长,放在以太网帧的最后,我们称之为CRC,然后把这个以太网帧从接口发送出去,为何要CRC?为了怕在传输过程中因为线路质量、或噪音引起数据的丢失或者改变,发送方计算一个CRC,覆盖范围为整个以太网帧,接收方收到一个帧,先把最后四个字节CRC拷贝出来,然后去掉CRC,再计算CRC,如果计算出的CRC和接收到的CRC一致,说明帧是完好的,可以接收,否则直接丢弃!好,现在ICMP已经发到网络上去了。


4. 10.0.0.3这台主机发现这个帧的目的地址和自己的一样,哦,这是我的地址,于是接收,步骤参见步骤三,网卡把这个帧放在自己的缓存,发一个CPU中断,意思是收到一个帧,需要您老人家照顾一下,于是TCP/IP栈把这个帧移到自己的缓存空间,交由ICMP进程来处理


5.  ICMP进程分析这个ICMP echo 请求,生成了回答ICMP echo reply报文,然后…剩下的步骤和以上的雷同,就不再罗嗦了。


6. ICMP echo reply 到达10.0.0.2主机,然后ping把这个消息输出到屏幕,这就完成了同一网段主机的通信。


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值