当 bytearray 转换为字符串时,Java 服务器套接字给出错误的输出。 C套接字头格式
int tccode 4
int len 4
char data[4088] 4088
C 结构格式
Tc Code :1001 Size : 256
#ifdef __DTGPL1T__
struct DTGPL1T_S
{
// ENTRY ZONE
short por1cur;
short por2cur;
short por1ten;
short por2ten;
short p1lvim1;
short p1lvim2;
short p1lvim3;
short p2lvim1;
short p2lvim2;
short p2lvim3;
short brc1 ;
short entrylt; short enlopcar;
short notchlen;
short poruse;
short p1remain;
short p2remain;
short eloopcap;
short elooplen;
short untielen;
short entryspd;
short st8ten;
short brc2 ;
short scbtns;
short scbel ;
short scb1intr;
short scb2intr;
short scb3intr;
short st3ten;
short brc3 ;
short plettkts;
short deli1ten;
short d1loopcc;
short d1loopln;
short d1loopcp;
short brc4 ;
short br4ten;
short plcspd;
short triwidt;
short sthosingwidth ;
short trigap1;
short trigap2;
short trigap3;
short trigap4;
short trilap1;
short trilap2;
short trilap3;
short trilap4;
short aactwid;
short adevwid;
short chopw ;
short chopd ;
short tristat;
short trispd;
short trmtoplen;
short deli2ten;
short d2loopcc;
short d2loopcp;
short d2loopln;
short br5ten;
short brc5 ;
short wpd1sta;
short wpd2sta;
short wpd3sta;
short wpd3asta;
short wpd4sta;
short wpd5sta;
short chvsen[2];
short wbsen[2];
short etcsen;
short wpdpass[6];
short wpdlen[6];
short pl_cv_next_move;
short ccv1_lock_curr ;
short ccv2_lock_curr ;
short ewb1_lock_curr ;
short ewb2_lock_curr ;
short etc_lock_curr ;
short eskd1_lock_curr;
short eskd2_lock_curr;
short ecc1_lock_curr ;
short ecc2_lock_curr ;
short st_wid_low_err ;
short st_wid_upp_err ;
short trim_width_set;
short hadling_time;
short spare01[14] ;
short spare02[16] ;
//38 + 16 = 53
};
typedef struct DTGPL1T_S DTGPL1T_T;
typedef DTGPL1T_T *DTGPL1T_P;
#define DTGPL1T_LN sizeof(DTGPL1T_T)
#endif // Eof of __DTGPL1T__
和 Java 服务器代码
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
//DataInputStream in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
int tcCode = in.readInt();
int length = in.readInt();
if(tcCode == 1001) {
byte[] messageByte = new byte[length];
boolean end = false;
StringBuilder dataString = new StringBuilder(length);
int totalBytesRead = 0;
while(!end) {
int currentBytesRead = in.read(messageByte);
totalBytesRead = currentBytesRead + totalBytesRead;
if(totalBytesRead <= length) {
dataString
.append(new String(messageByte, 0, length - totalBytesRead + currentBytesRead));
} else {
dataString
.append(new String(messageByte, 0, length - totalBytesRead + currentBytesRead));
}
if(dataString.length()>=length) {
end = true;
}
}
System.out.println("Message1 "+dataString);
}
MessageBytes 越来越像 [-1, -2, 0, 0, 0, 0, 0, 0, 0, 35, 0, 33, 0, 30, 0, 45, 0, 40, 0, 35, 0, 0, 0, 0, -1, -1, 0, 10, 0, 1, 0, 1, 0, 1, 5, -123, 0, 111, 3, 34, 0 , 0, 0, 0, 0, 0, 2, -25, 0, 24, -1, -2, -1, -3, 0, 0, 0, 0, 0, 0, 43, 37, -1 , -35, 0, 0, 0, 72, 10, 42, 0, 0, 43, 37, 0, 0, 49, 126, 112, -30, 0, 5, 0, 5, 0, 11, 0 , 12, -3, 68, -3, 68, -6, -20, -6, -20, 27, 86, 0, 0, 0, 16, 0, 16, 0, 0, 0, 0, 0 , -13, -1, -7, 0, 0, 16, 107, 0, -99, 0, 80, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 , 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 1, -20, 4, -73, -1, 74, -1] [输出截图] 1
最佳答案
与 C 不同,Java String 不适合保存字节。将字节转换为字符串 decodes字节,这意味着某些值可能会被更改或丢失。
即使没有更改任何值,您的数据也不会表示字符,因此将其打印为文本将显示无意义。例如,您的许多字节为零,在输出中根本不显示,因为字符 \u0000
是非打印控制字符。
您应该完全避免使用 Strings 和 StringBuilders。相反,仅将字节存储在字节数组中:
while (totalBytesRead < length) {
int currentBytesRead = in.read(messageByte,
totalBytesRead, length - totalBytesRead);
totalBytesRead = currentBytesRead + totalBytesRead;
}
您的数据似乎完全由 short
值组成,因此,假设 C 客户端构建为将 short
视为 16 位值,并假设 C 编译器没有填充您的 struct
成员以便对它们进行字对齐,您可以使用 ByteBuffer 将字节转换为短裤序列和 ShortBuffer :
ByteBuffer buffer = ByteBuffer.wrap(messageByte);
ShortBuffer shortBuffer = buffer.asShortBuffer();
要打印它们,将它们作为数组检索并使用 Arrays.toString :
short[] values = new short[length / 2];
shortBuffer.get(values);
System.out.println(Arrays.toString(values));
关于java - C 客户端套接字数据无法在 Java 服务器中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58054558/