如何用javasocket编程解码C类结构数据包
java!中的socket编程新手!。我正在尽我最大的努力去理解javasocket编程,以及如何解码类似“C”的数据包
客户端是python,它在标记之间发送数据包,
示例有效负载:<tag1> data packet 1</tag1><tag2>data packet 2</tag2>
有一个c代码,用于接收有效载荷并对有效载荷进行结构解码,所有标签均为30字节,数据包1,2,。。n将具有不同的结构
我对java程序相当陌生,在通过web搜索之后,我可以编写一个socket服务器,从客户端接收有效负载,现在面临数据包解码问题。 我可以显示字节。所以使用数组。copyOfRange方法来获取数据
分组数据如下所示:
typedef struct {
unsigned char dataType;
unsigned char value[4];
} GEN_VAL
typedef struct {
unsigned char dataType;
unsigned char numBytes;
unsigned char value[32];
} GEN_STR_32;
typedef struct {
char startTag[32];
GEN_STR_32 c_code;
GEN_STR_32 c_name;
GEN_STR_32 c_info;
GEN_VAL i_type;
GEN_VAL i_count1;
GEN_VAL i_count2;
char endTag[32];
} DATA_PACKET_1;
我用下面的代码片段接收缓冲区
DataInputStream inStream = new DataInputStream
(new BufferedInputStream(socket.getInputStream()));
while ( ( noOfBytes = (int)inStream.read(recvBuff)) != -1)
{
cDecode mydecode = new cDecode();
mydecode.decodePacket(noOfBytes, recvBuff);
}
cDecode。爪哇
public void decodePacket(int TotalBytes, byte[] BuffRecv)
{
byte[] GetTag = new byte[32];
byte[] GEN_STR_32 = new byte[32];
byte[] GEN_INT_4 = new byte[4];
GetTag = Arrays.copyOfRange(BuffRecv,0,31);
String TagStr = new String(GetTag).trim(); //get start tag
int startloc = 31;
int offset = startloc + 32;
GEN_STR_32 = Arrays.copyOfRange(Buff,startloc,offset);
String cCode = new String(GEN_STR_32).trim(); // get value of cCode
System.out.println("Code :" + cCode );
startloc = offset;
offset = startloc + 32;
GEN_STR_32 = Arrays.copyOfRange(Buff,startloc,offset);
String cName = new String(GEN_STR_32).trim(); //get value of cName
System.out.println("Name:" + cName );
startloc = offset;
offset = startloc + 32;
GEN_STR_32 = Arrays.copyOfRange(Buff,startloc,offset);
String cInfo = new String(GEN_STR_32).trim(); //get value of cName
System.out.println("Info:" + cInfo );
startloc = offset;
offset = offset + 4;
ByteBuffer iTypeByteBuff = ByteBuffer.wrap(GEN_DATA_INT_4);
int iType= iTypeByteBuff .getInt();
System.out.println("type :" + iType);
startloc = offset;
offset = offset + 4;
// likewise used ByteBuffer for remaining integer data
// for receiving end tag, offset is added with 32!
}
前3个数据是字符串值,
第二个3数据具有整数值
字符串值显示正确
在将字节转换为整数时发现问题,不确定数组中的STARTOC和offset值是否正确。copyOfRange方法
我根据从网上得到的信息尝试了这个方法
我还了解到,对于所有数据结构,都有一个不带方法的独立类。但我找不到任何完整的示例,因为java中没有“sizeof”
有人能告诉我在这种情况下解码数据包的正确方法吗
# 1 楼答案
对于字节数组或输入/输出,可以使用字节缓冲
还有一个二进制格式标准ASN,它的工作方式更像语法,但在这种情况下,上面的方法就可以了
C端的一个问题是现场对齐和平台可移植性。可以使用宏将结构转换为完全指定的二进制数据结构构建调用
在评论之后,使用DataInputStream
您似乎没有对DataInputStream使用特定于数据的读取调用
DataInputStream可能更直接。ByteBuffer具有可指定字节顺序的优势,因为java默认为BIG_ENDIAN
# 2 楼答案
如果您认为数据是一个要作为数据类型读取的流,那么可以扩展
DataInputStream
来创建一个PacketInputStream
具有readDataPacket()
方法。定义一个DataPacket
类来保存CDATA_PACKET_1
结构中的数据首先是用来保存数据的类:
以及解码数据包的
DataInputStream
实现:调用代码将执行以下操作:
我只需要重写
DataPacket.toString()
,然后执行System.out.println(p)
,但这里已经有足够的代码了。此外,我会存储基元类型,而不是使用GenValue
类,但我对实际数据了解不够,无法解决这个问题