2012-05-24 88 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 
      ); 
     } 
    } 
相关问题