我正在尝试让C99客户端与Java服务器通信。但是,Java服务器接收的数据与传输的数据不同。 (即@x @Ófl/ú. @¨ Û ÛÁBp'¡`Ôfl/)
我已经考虑过这是一个编码问题,但是我遇到了一堵砖墙。我已经尝试测试这两个程序,得出结论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 :(得分:2)
我不确定C99是否提供了编码标准,但我认为它是特定于实现的。例如,它可能是US-ASCII
。
Java InputStreamReader
(或输出)使用在操作系统或Java安装中指定的默认字符集(不确定位置)会发生什么情况,因此与C程序使用的字符集相比可能会有所不同。
你能做的最好的事情是测试各种编码,InputStreamReader
类确实提供了一个特定的构造函数:
public InputStreamReader(InputStream in, Charset cs)
允许您指定要使用的字符集。看看here是否有可能的字符集。
答案 1 :(得分:1)
您还必须查看endian差异:Java使用network order,而C主机可能不会。 ByteBuffer
,here,可能会有帮助。
答案 2 :(得分:1)
如果我没错,你会有类似的东西:
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
使用&amp; message:
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 .
可以做的另一个hack / debug / thing就像:
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
);
}
}
答案 3 :(得分: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);