2015-04-03 26 views
0

我很難從C服務器傳遞一個簡短值。我在另一端收到的是它看起來像是'垃圾',我似乎無法將其轉化爲有用的東西。C服務器到Java客戶端套接字讀取傳遞的值很短

因素我認爲是影響它

  1. 二進制補
  2. 潛在ASCII或UTF-8 enconding

與C語言代碼開始:

 // Read 10 bit value into short 
     unsigned short ret = decideActionCall(buffer); 
     unsigned char lsb = (unsigned char) ret; 
     unsigned char msb = (unsigned char) (ret >> 8); 

     printf("msb,lsb = %02x,%02x\n",msb, lsb); 

     /** 
     char retString [4]; 
     retString[0] = msb; 
     retString[1] = lsb; 
     retString[2] = '\n'; 
     retString[3] = '\0'; 
     */ 

     unsigned short retString1[1]; 
     retString1[0] = ret; 

     printf("msb,lsb = %d,%d\n",retString[0],retString[1]); 

     printf("String to send: <%s>\n",retString1); 
     //if (write(newsockfd, retString, 3) < 0) { 
     // error("Error sending response to the server"); 
     //} 
     if (write(newsockfd, &retString1, 2) < 0) { 
      error("Error sending response to the server"); 
     } 
     if (write(newsockfd, "\r",1) < 0) { 
      error("Error sending response to the server"); 
     } 

和終端輸出是

START----------------------------- 

0 0 
136 0x88 
ADC3 = 136 

END----------------------------- 
decideActionCall() ret value: 136 
msb,lsb = 00,88 
msb,lsb = 0,136 
String to send: <�> 

所以'ret'的返回值是介於0和1023(0x3FF)之間的值。這10位需要從C服務器傳輸到客戶端。我嘗試過兩種實現方式,我將它們發送爲8位字符(retString)或一個16位短(retString1)。 Sizeof(char) == 1sizeof(short) == 2

的Java代碼(有各種嘗試解析它):

BufferedReader bufIn = new BufferedReader(new InputStreamReader(in)); 
String response = bufIn.readLine(); 

char [] hello = response.toCharArray(); 
for (char a : hello) { 
    short shortA = (short) (a & 0x3FF); 
    System.out.println(a + " = " + (int)a + " = " + shortA); 


    //System.out.println((int)a); 
    //System.out.println(Integer.valueOf(a+"",10)); 
    } 

byte test[] = response.getBytes("UTF-8"); 

StringBuilder sb = new StringBuilder(); 
for (byte b : test) { 
    sb.append(String.format("%02X ", b)); 
} 
System.out.println(sb.toString()); 

byte b05 = 0x00; 
byte b06 = 0x00; // MSB, positive as < 0x80 

int i = 0; 
for (byte a : test) { 
    //System.out.println(short1); 
    System.out.println("byte: " + a); 
    //System.out.println(Integer.valueOf(a+"",10)); 

    if (i == 0) { 
     b05 = a; 
    } else { 
     b06 = a; 
    } 

    i++; 
    } 

    System.out.println("i = " + i); 

    byte[] byteTabDay = new byte[2]; 
    byteTabDay[0] = b05; 
    byteTabDay[1] = b06; 

    BigInteger temp = new BigInteger(test); 
    System.out.println(temp); 
    System.out.println(temp.intValue()); 
    System.out.println(temp.shortValue() + 65536); 

    BigInteger temp2 = new BigInteger(byteTabDay); 
    System.out.println(temp2); 
    System.out.println(temp2.shortValue() + 65536); 

Java示例輸出(Android的logcat的):

I/System.out﹕ response: ��� 
I/System.out﹕ here: � 65533 
I/System.out﹕ ascii: 65485 65581 
I/System.out﹕ � = 65533 = 1021 
I/System.out﹕ �� = 0 = 0 
I/System.out﹕ EF BF BD 00 
I/System.out﹕ byte: -17 
I/System.out﹕ byte: -65 
I/System.out﹕ byte: -67 
I/System.out﹕ byte: 0 
I/System.out﹕ i = 4 
I/System.out﹕ -272646912 
I/System.out﹕ -272646912 
I/System.out﹕ 48384 
I/System.out﹕ -4352 
I/System.out﹕ 61184 

問題:

  1. 我應該如何正確讀取套接字?
  2. 如何正確讀取10位? (我已經嘗試用0x3FF掩蓋字符)
  3. 是兩個補碼可能導致問題嗎?

謝謝

+1

如果你想要一個16位整數,不要使用'short',因爲short的大小是實現定義的。改爲使用'uint16_t' - 它被定義爲16位。您還想按網絡順序讀取和寫入多字節整數。也嘗試用十六進制打印你的Java輸出。 – 2015-04-03 23:06:02

+0

謝謝你的迴應。我將這些值更改爲uint16_t和unint8_t(如果可用)。我還使用1和0給出的鏈接將其更改爲網絡字節順序。我也打印了十六進制,但仍然混亂。我實施了EJP建議的更改,似乎已經奏效。 – koala123 2015-04-03 23:33:37

+0

此外,請考慮使用協議緩衝區而不是手動推送二進制數據。 – chrylis 2015-04-04 00:04:13

回答

2
  1. 您收到二進制,所以你不應該使用Reader可言。您應該使用DataInputStream.readShort().
  2. 這是正確的。
+0

謝謝你的迴應。我實施了這一改變,我相信這是修復。我始終獲得正確的價值。 – koala123 2015-04-03 23:34:16

相關問題