C99客户端与Java服务器进行通信
我在尝试让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);
我不知道,如果C99提供了编码标准,但我想这是实现特定的。例如,它可能是US-ASCII
。
发生什么事是Java InputStreamReader
(或输出)使用在OS或Java安装中某处(不知道在哪里)指定的默认字符集,因此它可能与C程序使用的字符集不同。
你能做的最好的事情是测试不同的编码,该InputStreamReader
类确实提供了一个特定的构造函数:
public InputStreamReader(InputStream in, Charset cs)
中,你被允许指定要使用的字符集。看看here可能的字符集。
C客户端根据nl_langinfo(CODESET)使用US-ASCII字符集,所以它不是字符编码问题。我也强迫Java服务器使用InputStreamReader而不使用这个字符集。 – Khronos
您的问题看起来像字节对齐
在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);
如果我没看错你有这样的:
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
);
}
}
什么是从C消息的编码? – nhahtdh
所以我的回答是正确的;) – Morpfh