【问题标题】:C Client socket data not able to read in Java ServerC客户端套接字数据无法在Java服务器中读取
【发布时间】:2020-01-23 01:24:14
【问题描述】:

当 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

【问题讨论】:

  • 请包含 tccode 和 len 以及您从 C 端输入到听者的文本中的消息。我在黑暗中拍摄:字节顺序不一致,一个是小端,另一个是大端
  • C、C++ 和 Java 怎么样?
  • @bigdataolddriver请检查编辑的问题我添加了C结构格式,有3个结构tc_code 1001 Size 256, tc_code 1002 Size 512, tc_code 1003 Size 280*3
  • Java 不是 C。在 Java 中,您永远不应该使用字符串来保存字节。为此使用字节数组。从字节数组中创建字符串可能会损坏某些值,因为它们不会都表示有效字符。
  • 1. String 不是二进制数据的容器。 2. 你应该在这里使用DataInputStream.readShort(),但要注意字节序问题。 3. 不要使用结构体作为网络协议。有十几种方法可能会出错,或者在不同版本之间发生变化。您需要为自己编写一个适当的独立于语言的协议定义,并实现一个 C 和一个 Java 库来发送和接收它。

标签: java c sockets tcp


【解决方案1】:

与 C 不同,Java 字符串不适合保存字节。将字节转换为字符串decodes 字节,这意味着某些值可能会被更改或丢失。

即使没有更改任何值,您的数据也不会代表字符,因此将其打印为文本将显示无意义。例如,您的许多字节都是零,这根本不会显示在输出中,因为字符 \u0000 是非打印控制字符。

您应该完全避免使用 Strings 和 StringBuilders。相反,只将字节存储在字节数组中:

while (totalBytesRead < length) {
    int currentBytesRead = in.read(messageByte,
        totalBytesRead, length - totalBytesRead);
    totalBytesRead = currentBytesRead + totalBytesRead;
}

您的数据似乎完全由 short 值组成,因此,假设 C 客户端构建为将 short 视为 16 位值,并且假设 C 编译器没有填充您的 struct 成员为了对它们进行字对齐,您可以使用 ByteBufferShortBuffer 将字节转换为短序列:

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));

【讨论】:

  • 我用你上面的代码打印值 [-1, 0, 0, 0, 35, 33, 30, 45, 40, 35, 0, 0, -1, 10, 1, 1, 1, 1413, 111, 802, 0, 0, 0, 717, 24, -2, -3, 0, 0, 0, 10445, -35, 0, 72, 2602, 0, 10445, 0, 12670, 28898 , 5, 5, 11, 12, -700, -700, -1300, -1300, 6998, 0, 16, 16, 0, 0, 243, -7, 0, 4203, 157, 80, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -20, 1207, -182, -21, 470, -237, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 12670, 13106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1002, 0, 4096] 这种格式
  • 这是您期待的数据吗?
  • 不对,byte应该可以转成char或者string
  • 我不确定这意味着什么。 por1cur 的一些示例值是什么?你是说它包含一个字符值?
  • 您的解决方案适用于所有短值,但如果 struct 包含一些 int 和字符值,它将如何工作。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 2012-05-26
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多