解码字节到ipaddress

decoding bytes to ipaddress

我有一个 java 应用程序侦听套接字上的更新数据包。我向它发送原始字节,然后将其转换为 IP 地址。数据包由 9 个字节组成。 4 个用于第一个地址,然后 1 个用于掩码,另外 4 个字节用于第二个地址。

奇怪的是2地址的2字节打印出了错误的值。为什么?

package net.floodlightcontroller.openlisp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import net.floodlightcontroller.packet.IPv4;

public class UdpServerCp extends Thread {

    protected OFLISPRules oflr = OFLISPRules.getInstance();
    private static UdpServerCp instance;
    private int priority = 3;

    public static synchronized UdpServerCp getInstance() {
        if (instance == null)
        instance = new UdpServerCp();
        return instance;
    }

    public void run() {

        OpenlispHandler oh = OpenlispHandler.getInstance();

        byte[] receiveData = new byte[9];
        DatagramPacket receivePacket;
        System.out.println("Waiting to receive...");
        DatagramSocket serverSocket;
        try {
            serverSocket = new DatagramSocket(8888);

            while (true) {
                receivePacket = new DatagramPacket(receiveData, receiveData.length);

                serverSocket.receive(receivePacket);

                // if i receive a packet and it doesn't already have a flow rule
                // process it
                if ((receivePacket != null) && (oh.isNewOFRuleAdded() == false)){
                    byte[] bytes = receivePacket.getData();


                    //int eidInteger = ((int)bytes[3] << 8*3) + ((int)bytes[2] << 8*2) + ((int)bytes[1] << 8) + ((int) bytes[0]);
                    int eidInteger = ((int)bytes[0] << 8*3) + ((int)bytes[1] << 8*2) + ((int)bytes[2] << 8) + ((int) bytes[3]);
                    String eidAddressString = InetAddress.getByAddress(unpack(eidInteger)).getHostAddress();
                    System.out.println("buffer EID: " + eidAddressString);

                    int prefixInteger = (int) bytes[4];
                    System.out.println("buffer PREFIX: " + prefixInteger);

                    int rlocInteger = ((int)bytes[5] << 8*3) + ((int)bytes[6] << 8*2) + ((int)bytes[7] << 8) + ((int) bytes[8]);
                    String rlocAddressString = InetAddress.getByAddress(unpack(rlocInteger)).getHostAddress();
                    System.out.println("buffer RLOC: " + rlocAddressString);



                    IPv4 eidADD = new IPv4();
                    IPv4 rlocADD = new IPv4();
                    eidADD.setDestinationAddress(eidAddressString);
                    rlocADD.setDestinationAddress(rlocAddressString);

                    oflr.rlocOFRule(eidADD, prefixInteger, rlocADD, priority);
                    oh.setNewOFRuleAdded(true);
                    this.priority++;
                }
            }
        } catch (SocketException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    byte[] unpack(int bytes) {
        return new byte[] { 
                (byte) ((bytes >>> 24) & 0xff),
                (byte) ((bytes >>> 16) & 0xff), 
                (byte) ((bytes >>> 8) & 0xff), 
                (byte) ((bytes) & 0xff) };
    }
}

当您将一个字节转换为一个整数时,您可能会得到负数。由于 218 是一个负字节值,这会发生在这里并导致前一个字节递减。

int rlocInteger = ((int)bytes[5] << 8*3) + ((int)bytes[6] << 8*2) + ((int)bytes[7] << 8) + ((int) bytes[8]);

要解决此问题,请使用 0xff 进行屏蔽,例如:((bytes[5]&0xff) << 8*3)

我认为没有理由通过一个整数从 9 字节数组中获取 4 个字节,只需复制您需要的子数组即可。类似于:

byte[] bytes = receivePacket.getData();
String eidAddressString = InetAddress.getByAddress(Arrays.copyOfRange(bytes, 0, 4)).getHostAddress();
System.out.println("buffer EID: " + eidAddressString);

int prefixInteger = (int) bytes[4];
System.out.println("buffer PREFIX: " + prefixInteger);

String rlocAddressString = InetAddress.getByAddress(Arrays.copyOfRange(bytes, 5, 9)).getHostAddress();
System.out.println("buffer RLOC: " + rlocAddressString);