计算机网络—地址解析协议ARP

ARP协议的用途是为了从网络层使用的IP地址,解析出在数据链路层使用的硬件地址

 

IP地址和下面的网络的硬件地址之间由于格式不同而不存在简单的映射关系,此外,在一个网络上可能经常会有新的主机加入进来,或撤走一些主机。更换网络适配器也会使主机的硬件地址改变。地址解析协议ARP解决这个问题的方法是在主机ARP高速缓存中存放一个从IP地址到硬件地址的映射表,并且这个映射表还经常动态更新。

每一台主机都设有一个ARP 高速缓存,里面有本局域网上的各主机和路由器的IP地址到硬件地址的映射表,这些都是该主机目前知道的一些地址。那么主机怎样知道这些地址呢?

当主机A要向本局域网上的某台主机B发送IP数据报时,就先在其ARP高速缓存中查看有无主机B的IP地址。如有,就在ARP高速缓存中查出其对应的硬件地址,再把这个硬件地址写入MAC帧,然后通过局域网把该MAC顿发往此硬件地址。

也有可能查不到主机B的IP地址的项目。这可能是主机B才入网,也可能是主机A刚刚加电,其高速缓存还是空的。在这种情况下,主机A就自动运行ARP,然后按以下步骤找出主机B的硬件地址:

1、ARP进程在本局域网上广播发送一个ARP请求分组

2、在本局域网上的所有主机上运行的ARP进程都收到此ARP请求分组。

3、主机B的IP地址与ARP请求分组中要查询的IP地址一致,就收下这个ARP请求分组,并向主机A发送ARP响应分组,同时在这个ARP响应分组中写入自己的硬件地址。虽然ARP请求分组是广播发送的,但ARP响应分组是普通的单播,即从一个源地址发送到一个目的地址。

 

 4、主机A收到主机B的ARP响应分组后,就在其ARP高速缓存中写入主机B的IP地址到硬件地址的映射。

当主机A向B发送数据报时,很可能以后不久主机B还要向A发送数据报,因而主机B也可能要向A发送ARP请求分组。为了减少网络上的通信量,主机A在发送其ARP请求分组时,就把自己的IP地址到硬件地址的映射写入ARP请求分组。当主机B收到A的ARP请求分组时,就把主机A的这一地址映射写入主机B自己的ARP高速缓存中。以后主机B向A发送数据报时就很方便了。

ARP对保存在高速缓存中的每一个映射地址项目都设置生存时间。凡超过生存时间的项目就从高速缓存中删除掉。

请注意,ARP是解决同一个局域网上的主机或路由器的IP地址和硬件地址的映射问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ARP协议地址解析协议)是一种用于将网络地址(如IP地址解析为数据链路层地址(如MAC地址)的协议。其工作原理如下: 1.当主机A需要向主机B发送数据时,首先检查其ARP高速缓存(ARP Cache)中是否有主机B的IP地址对应的MAC地址。如果有,则直接将数据帧发送给主机B的MAC地址;如果没有,则执行第2步。 2.主机A向网络广播一个ARP请求包,请求包中包含主机A的IP地址和MAC地址,以及主机B的IP地址网络中所有主机都会收到这个请求包,但只有主机B会响应。 3.主机B收到ARP请求包后,会向主机A单独发送一个ARP响应包,响应包中包含主机B的IP地址和MAC地址。 4.主机A收到ARP响应包后,将主机B的IP地址和MAC地址存入其ARP高速缓存中,并将数据帧发送给主机B的MAC地址。 下面是一个简单的Python实现,用于发送ARP请求并接收ARP响应: ```python import socket import struct def get_mac_address(ip_address): # 创建ARP请求包 arp_request = struct.pack("!HHHBBH6s4s6s4s", # ARP请求包格式 0x0001, # 硬件类型:以太网 0x0800, # 协议类型:IPv4 0x0006, # 硬件地址长度:6 0x0004, # 协议地址长度:4 0x0001, # 操作类型:ARP请求 b"\x00\x00\x00\x00\x00\x00", # 发送方MAC地址 socket.inet_aton("192.168.1.100"), # 发送方IP地址 b"\x00\x00\x00\x00\x00\x00", # 目标MAC地址 socket.inet_aton(ip_address)) # 目标IP地址 # 创建套接字并发送ARP请求包 s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.SOCK_RAW) s.bind(("eth0", socket.SOCK_RAW)) s.send(arp_request) # 接收ARP响应包 while True: packet = s.recvfrom(2048)[0] eth_header = struct.unpack("!6s6sH", packet[:14]) if eth_header[2] == 0x0806: # 如果是ARP响应包 arp_header = struct.unpack("2s2s1s1s2s6s4s6s4s", packet[14:42]) if socket.inet_ntoa(arp_header[6]) == ip_address: return ":".join("{:02x}".format(ord(c)) for c in arp_header[5]) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值