2012-05-24 133 views
1

我在嘗試讓C99客戶端與Java服務器進行通信。但是,Java服務器接收的數據與傳輸的數據不同。 (即@x @Ófl /ú. @¨ Û¢ÁBp'¡ÔÔfl /)C99客戶端與Java服務器進行通信

我已經設想這是一個編碼問題,但我碰到了一堵磚牆。我試過測試這兩個程序得出結論:Java服務器能夠與Java客戶端進行通信,並且C客戶端能夠與C服務器進行通信。

但是我無法讓Java服務器與C客戶端通信。

Java代碼:

serverSocket = new ServerSocket(port); 
Socket sock = serverSocket.accept();        

BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream())); 

String inputString = in.readLine(); 
System.out.println(inputString); 

C代碼:

struct sockaddr_in sin; 
struct hostent *host; 

host = gethostbyname(hostname); 

bzero(&(sin.sin_zero),8); 
sin.sin_port = htons(port); 
sin.sin_addr = *((struct in_addr *)host->h_addr); 
sin.sin_family = AF_INET; 

sock = socket(AF_INET, SOCK_STREAM, 0); 

if(connect(sock, (struct sockaddr *)&sin,sizeof(struct sockaddr_in)) == -1) 

...

send(sock, &message, strlen(message)+1, 0); 

編輯:我試過發送兩者之間的單詞 'TEST'主機沒有成功。

修復:我在消息變量前面有一個&符號,正如我傳遞的那樣。

本來應該是:

send(sock, message, strlen(message)+1, 0); 
+0

什麼是從C消息的編碼? – nhahtdh

+0

所以我的回答是正確的;) – Morpfh

回答

2

我不知道,如果C99提供了編碼標準,但我想這是實現特定的。例如,它可能是US-ASCII

發生什麼事是Java InputStreamReader(或輸出)使用在OS或Java安裝中某處(不知道在哪裏)指定的默認字符集,因此它可能與C程序使用的字符集不同。

你能做的最好的事情是測試不同的編碼,該InputStreamReader類確實提供了一個特定的構造函數:

public InputStreamReader(InputStream in, Charset cs) 

中,你被允許指定要使用的字符集。看看here可能的字符集。

+0

C客戶端根據nl_langinfo(CODESET)使用US-ASCII字符集,所以它不是字符編碼問題。我也強迫Java服務器使用InputStreamReader而不使用這個字符集。 – Khronos

1

你還必須看endian不一致:Java使用network order,而C主機可能不。 ByteBuffer,說明here,可能有所幫助。

0

您的問題看起來像字節對齊

C客戶端,您需要將主機到網絡字節順序轉換。

使用

uint32_t htonl(uint32_t hostlong); 

uint16_t htons(uint16_t hostshort); 

uint32_t ntohl(uint32_t netlong); 

uint16_t ntohs(uint16_t netshort); 
+0

我正在發送文本,而不是原始數字。 – Khronos

+0

請參考此問題發送字符數組http://stackoverflow.com/q/526030/143897 –

+0

發送單詞「測試」從客戶端到服務器無法正常工作。該消息沒有任何數字,所以我懷疑這是問題。 – Khronos

0

如果我沒看錯你有這樣的:

char *message = "Hello"; 

當您發送通過:

send(sock, &message, strlen(message)+1, 0); 
      | 
      +---- Err. 

您發送郵件的地址,而不是消息本身,進一步你設置消息的長度和這種填充垃圾的長度。

如果你這樣做,而不是:

send(sock, message, strlen(message)+1, 0); 

它應該工作。

或者使用char message[] = "Hello"; ...


爲了進一步剖析,你可以做類似的服務器數據:

 int i = 0; 
     for (char ch : inputString.toCharArray()) { 
      System.out.printf("%2d: 0x%02X o%03o %3d %c%n", 
       i++, 
       (int)ch & 0xff, 
       (int)ch & 0xff, 
       (int)ch & 0xff, 
       Character.isISOControl(ch) ? '.' : ch 
      ); 
     } 

 buf = inputLine.getBytes(/* charset */); 
     for (i = 0; i < buf.length; ++i) { 

Client siad: Hello 
0: 0x00 o000 0 . 
1: 0x48 o110 72 H 
2: 0x65 o145 101 e 
3: 0x6C o154 108 l 
4: 0x6C o154 108 l 
5: 0x6F o157 111 o 

使用&消息:

Client said: `� 
0: 0x60 o140 96 ` 
1: 0xEF o357 239 ￯ 
2: 0xBF o277 191 ﾿ 
3: 0xBD o275 189 ᄑ 
4: 0x04 o004 4 . 
5: 0x08 o010 8 . 

另一個黑客/調試/的事情之一,可以做的是一樣的東西:

while (true) { 
     in.mark(128); 
     if ((inputLine = in.readLine()) == null) 
      continue; 

     System.out.println("Response: " + inputLine); 

     in.reset(); 
     i = 0; 
     while (in.ready()) { 
      c = in.read(); 
      System.out.printf("%2d: 0x%02X o%03o %3d %c%n", 
       i++, 
       c, c, c, 
       Character.isISOControl((char) c) ? '.' : (char)c 
      ); 
     } 
    } 
相關問題