C++套接字-WString到Java套接字

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功能得到垃圾数据和发送功能没有按”似乎永远不会到达服务器。

在此先感谢。

+0

您应该显示用于发送和接收的C++代码或tcp转储,以便让我们了解Java程序应该接收和发送的内容。 – Joni 2014-11-23 20:17:14

第一:这个变量的肯定是混淆

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?否则你的代码不会编译。