如果 A (192.168.1.1 )向 B (192.168.1.2 )发送一个数据包,那么需要的条件有 ip、port、使用的协议(TCP/UDP)之外还需要 MAC 地址,因为在以太网数据包中 MAC 地址是必须要有的。那么怎样才能知道对方的 MAC 地址?答案是:它通过 ARP 协议来获取对方的 MAC 地址。ARP(Address Resolution Protocol,地址解析协议),是 TCP/IP 协议族中的一个,主要用于查询指定 ip 所对应的的 MAC(通过 ip 找 MAC)。请求方使用广播来发送请求,应答方使用单播来回送数据。收到返回消息后将该 IP 地址和物理地址存入本机 ARP 缓存中并保留一定时间,下次请求时直接查询 ARP 缓存以节约资源。以机器 A 获取机器 B 的 MAC 为例,A 广播发送一个 ARP 请求包,和 A 同在一个局域网的主机都会收到这个请求包,每个机器都会比较自己的 ip 和请求包的目的 ip 是不是一样的,如果不一样,就丢弃这个请求包,结果,只有 B 机器符合条件,B 机器单独给 A 发送 ARP 应答包,应答包带上了 B 的 ip 所对应的 MAC 地址,当 A 收到这个应答包后,就把 B 的 ip 以及其对应的 MAC 地址存入本机 ARP 缓存中。在 Linux 查看 ARP 缓存表:arp在 Windows 查看 ARP 缓存表:arp -aARP头部1、Dest MAC:目的 MAC 地址2、Src MAC:源 MAC 地址3、帧类型:0x08064、硬件类型:1(以太网)5、协议类型:0x0800(IP地址)6、硬件地址长度:67、协议地址长度:48、OP:1(ARP请求),2(ARP应答),3(RARP请求),4(RARP应答)接下来这个例子为,虚拟机(Ubuntu)获取 PC 机的 MAC 地址:先查看 ubuntu 的 ip 和 MAC 地址:源代码下载。------------------------------------------分割线------------------------------------------免费下载地址在 http://linux.linuxidc.com/用户名与密码都是www.linuxidc.com具体下载目录在 /2015年资料/4月/7日/Linux 常用编辑器之Vim/下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm------------------------------------------分割线------------------------------------------完整代码如下:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <net/if.h> //struct ifreq #include <sys/ioctl.h> //ioctl、SIOCGIFADDR #include <sys/socket.h> #include <netinet/ether.h> //ETH_P_ALL #include <netpacket/packet.h> //struct sockaddr_ll #include <netinet/in.h>int main(int argc,char *argv[]) { //1.创建通信用的原始套接字 int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));