以太网数据包如何发送 如图,求代码

图片说明

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

在以太网中数据包是如何发送的?ip和MAC有什么关系呢?下面所讲的数据传送只设计网络层和数据链路层。在linux下。
在局域网内,一台主机H1(192.168.1.110)想发送数据给主机H2(192.168.1.111)时。数据是怎样过去的呢?
首先H1会查看自己的route table(命令route查看):

Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
default 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

确定H2在同一局域网内,将数据包直接从网卡eth0发出。再查看arp table,获取H2的MAC地址(命令arp查看):

Address HWtype HWaddress Flags Mask Iface
192.168.1.1 ether 00:1d:0f:3e:95:46 C eth0

当arp中没有H2的IP到MAC映射时,H1需要广播一个frame,包含下面的几个值:

H1MAC || 广播MAC || H1IP || H2IP

局域网内所有主机都接受这个frame,因为是广播MAC(广播MAC为:FF-FF-FF-FF-FF-FF),所以都需解析它的数据内容,获得其中的目标IP。与自己的IP不匹配的主机直接忽略frame。匹配的主机发回一个frame,包含:

本机IP || 本机MAC || H1IP || H1MAC

这样H1就获得了H2的IP与MAC映射了。接着就进行frame的之间传输了(其他的主机无需解析出frame的IP,只要查看它的MAC是否与自己的匹配就行。也就是说无需提交到网络层,节省运算时间和资源)。

  自己解决了。贴上代码分享 
        //1枚举网卡并打开设备
    jpcap.NetworkInterface[] devices = JpcapCaptor.getDeviceList();
    NetworkInterface device = devices[2];
    JpcapSender sender = null;
    //2.原始类型数据包,这种包没有首部字节。UDPPacket、IPPacket有首部字节
    //需要设置udp.setIPv4Parameter(0,false,false,false,0,false,false,false,0,0,255,
    //       230,//230未定义协议
    //       InetAddress.getByName("192.168.1.100"),  
    //       InetAddress.getByName("192.168.1.102"));
    Packet udp = new Packet();
    try {
           sender = JpcapSender.openDevice(device);
    } catch (IOException e) {
        e.printStackTrace();
    } 
    EthernetPacket ether = new EthernetPacket();
    //设置自定义协议类型
    int type = Integer.decode("0x7799");
    ether.frametype = (short)type;
    byte[] desmac = stomac(macAddress);//目标mac地址
    byte[] srcmac = null;
    try {
        srcmac = stomac(getLocalMac(InetAddress.getLocalHost()));
    } catch (SocketException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } // 本机MAC数组
    ether.src_mac = srcmac;
    ether.dst_mac = desmac;
    udp.datalink = ether;
    //设置字节的数据以及长度
     byte[] data = new byte[54];
     String typeStr = "hello";
     byte[] types = ByteUtil.ToByte(typeStr);
     for (int i = 0; i < 2; i++) {
        data[i] = types[i];
     }
     udp.data = data;
     sender.sendPacket(udp);