C++套接字-WString到Java套接字
我有一个自定义协议的服务器(即时消息传递 - 该协议已经在桌面客户端上),我试图在Android应用上实现它。我已经设法打开服务器的套接字并发送一个4字节的整数,但是,我不能让Java发送一个字符串或从服务器接收(正确)一个字符串。C++套接字-WString到Java套接字
服务器使用C++编写,托管在Windows机器上,并使用wstring进行通信(以允许发送非ASCII字符)。我怎样才能让应用程序以正确的格式读取/写入套接字?我相信在这种用法中,一个wstring应该是一个UTF-16字符串,但我不确定该字符串的字节顺序。
到目前为止,这是Java代码(我已禁用的NetworkOnMainThread例外暂时,而测试):
private String recv_from_server() {
String ret = "";
char[] bytes = new char[8192];
try {
int in = sinput.read(bytes, 0, 8192);
if(in > 0) {
byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");
}
}
catch(Exception ex) {}
return ret;
}
private void send_to_server(String message) {
try {
soutput.write(message);
soutput.flush();
}
catch(Exception ex) {
((TextView)findViewById(R.id.chat_message_message)).setText(ex.toString());
}
}
@Override
protected void onStart() {
super.onStart();
refresh();
refresher = new Timer();
refresher.schedule(new RefresherEvt(), 15000);
if(open_connection() == true) {
String ret = "";
while(ret == "") {
ret = recv_from_server();
}
((TextView)findViewById(R.id.chat_message_message)).setText(ret);
send_to_server("test message");
}
}
我从recv_from_server功能得到垃圾数据和发送功能没有按”似乎永远不会到达服务器。
在此先感谢。
第一:这个变量的肯定是混淆
char[] bytes = new char[8192];
它和数组的字符称为字节,JAVA下肯定是不一样的东西的名字。
第二个:我不知道你在这里使用哪种类型的流。有些人可能会读焦炭直接一些可以从内部UTF-8转换为UTF-16等等......等等。
int in = sinput.read(bytes, 0, 8192);
但三:这并不做任何事情,只要我可以告诉:
byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");
你以为你有bytes
有效字符串(这实际上是个字符),并把它转变为一个字节数组中的UTF-8编码(被称为STR)。然后将其从UTF-8转换回ret
中的JAVA内部UTF-16编码。为什么不只是返回bytes.toString()
?
一种可能
你说的C代码的字符串又名wstring的。基于UTF-16或UCS2。对于Windows而言,据我所知。所以一个假设是你收到的数据是UTF-16编码,如果它实际上是UCS2,你仍然会覆盖BMP中的所有字符。所以我想尝试的第一件事是直接从UTF-16解码喜欢它:
byte[] bytes = new byte[BUFFERSIZE];
// Actually read bytes -- don't know
// if your stream can handle that
int n sinput.read(bytes,0,BUFFERSIZE);
// silently assume n % 2 == 0 and UTF-16 doesn't use surrogates
String str = new String(bytes,n,"UTF16-BE" /*"UTF16-LE"*/);
然而
性病:: wstring的格式大部分时间仅用于内部交涉因为对于大多数字符,您只有一个字符的字符串位置。你不必与变长编码作斗争。这对于UCS4来说是完全正确的,对于UTF-16来说也是如此。这给了它内部的一个很大的优势。 但对于外部表示又名。文件或因特网UTF-8是通用的,因为它很紧凑,不需要考虑字节数,ASCII仍然可以看作ASCII,没有任何散布的零字节..等等。
因此,即使没有看到C代码,我仍然会认为外部表示很有可能是UTF-8。在这种情况下,您只需要做:
byte[] bytes = new byte[BUFFERSIZE];
// Actually read bytes -- don't know
// if your stream can handle that
sinput.read(bytes,0,BUFFERSIZE);
String str = new String(bytes,BUFFERSIZE,"UTF8");
为了您soutput.write(......),你也得打个电话的getBytes( “UTF-8”)
此代码:
byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");
只会返回"[[email protected]"
形式的字符串,因为char[]
不会覆盖Object.toString().
双重转换也不会完成任何有用的操作。 当然char[]
阵列应该被称为chars
,而不是bytes
。它应该是:
return new String(chars, 0, in, "UTF-8"); // or UTF-16 or whatever you determine
我认为sinput
是围绕输入流BufferedReader
?否则你的代码不会编译。
您应该显示用于发送和接收的C++代码或tcp转储,以便让我们了解Java程序应该接收和发送的内容。 – Joni 2014-11-23 20:17:14