我有一个java应用程序,它监听套接字上的upd数据包。我发送原始字节然后转换为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) };
}
}
答案 0 :(得分:2)
当您将一个字节转换为int时,您可能会得到负数。由于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)
答案 1 :(得分:0)
我认为没有理由通过一个整数从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);