在java中从对象到字节数组再到字节数组的转换
我有两门课:TcpPacket和IpPacket。tcpPacket应存储在ip数据包的数据字段中。如何将tcpPacket对象可靠地转换为字节数组,以便将其存储在IpPacket的数据字段中?在另一端接收到数据包后,如何可靠地将其转换回数据包对象在java中从对象到字节数组再到字节数组的转换,java,serialization,bytearray,Java,Serialization,Bytearray,我有两门课:TcpPacket和IpPacket。tcpPacket应存储在ip数据包的数据字段中。如何将tcpPacket对象可靠地转换为字节数组,以便将其存储在IpPacket的数据字段中?在另一端接收到数据包后,如何可靠地将其转换回数据包对象 public static final class TcpPacket { int source; int destination; public Packet( int source, int destination )
public static final class TcpPacket {
int source;
int destination;
public Packet( int source, int destination ) {
this.source = source;
this.destination = destination;
}
public String toString() {
return "Source: " + source + ", Dest: " + destination;
}
}
public static final class IpPacket {
byte[] data;
IpPacket( byte[] data ){
this.data = data;
}
}
TcpPacket tcpPacket = new TcpPacket( <someint>, <someint> );
// the following doesn't work because tcppacket is not a byte array.
IpPacket ipPacket = new IpPacket( tcpPacket );
公共静态最终类TcpPacket{
int源;
int目的地;
公共数据包(int源,int目的地){
this.source=源;
this.destination=目的地;
}
公共字符串toString(){
返回“Source:+Source+”,Dest:+destination;
}
}
公共静态最终类iPacket{
字节[]数据;
IpPacket(字节[]数据){
这个数据=数据;
}
}
TcpPacket TcpPacket=新TcpPacket(,);
//由于tcppacket不是字节数组,因此以下操作不起作用。
IpPacket IpPacket=新的IpPacket(tcpPacket);
这通常是怎么做的
感谢Maricruzz这应该可以工作,只要在从序列化/反序列化函数接收对象后将其强制转换为类即可
public static byte[] objToByte(TcpPacket tcpPacket) throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
objStream.writeObject(tcpPacket);
return byteStream.toByteArray();
}
public static Object byteToObj(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
ObjectInputStream objStream = new ObjectInputStream(byteStream);
return objStream.readObject();
}
我想为您提供手动序列化类的方法
public static final class TcpPacket {
public byte [] toByteArray() {
ByteBuffer b = ByteBuffer.allocate(4 * 2);
return b.putInt(source).putInt(destination).array();
}
public static TcpPacket fromByteArray(byte [] bytes) {
if (bytes.length < 8) throw new IllegalArgumentException("not enough bytes");
ByteBuffer b = ByteBuffer.wrap(bytes);
int source = b.getInt();
int destination = b.getInt();
return new TcpPacket(source, destination);
}
}
公共静态最终类TcpPacket{
公共字节[]toByteArray(){
ByteBuffer b=ByteBuffer.allocate(4*2);
返回b.putInt(源).putInt(目标).array();
}
来自ByteArray的公共静态TcpPacket(字节[]字节){
如果(bytes.length<8)抛出新的IllegalArgumentException(“字节不足”);
ByteBuffer b=ByteBuffer.wrap(字节);
int source=b.getInt();
int destination=b.getInt();
返回新的TcpPacket(来源、目的地);
}
}
添加一个toByteArray
和一个来自ByteArray的静态方法可以满足您的需要,并具有以下好处:
- 非常小的表示,只有8个字节,理论上可以用可变长度的整数编码更小
- 不会使您的应用程序暴露于Java序列化安全问题,因为很明显,您将从网络连接反序列化数据
如果您需要序列化更复杂的数据结构,我强烈建议您选择一个完善的序列化库,例如(我个人选择的武器),或者选择一个不会遭遇Java序列化这一安全噩梦的库。可能的重复请参阅