C++套接字 - wstring 到 Java 套接字
C++ socket - wstring to Java socket
我有一个带有自定义协议的服务器(用于即时消息 - 该协议已经在桌面客户端上就位),我目前正在尝试在 Android 应用程序上实现它。
我已经设法打开服务器的套接字并发送一个 4 字节整数,但是,我无法让 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函数获取垃圾数据,而发送函数似乎从未到达服务器。
提前谢谢。
此代码:
byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");
将只返回一个形式为 "[B@nnnnnn"
的字符串,因为char[]
不会覆盖Object.toString().
双重转换也不会完成任何有用的事情。当然,char[]
数组应该被称为chars
,而不是bytes
。它应该是:
return new String(chars, 0, in, "UTF-8"); // or UTF-16 or whatever you determine
我假设sinput
是围绕输入流的BufferedReader
?否则,您的代码将无法编译。
首先:这个变量的名称肯定令人困惑
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 转换回 JAVA 内部 UTF-16 编码,ret
.为什么不直接返回bytes.toString()
?
一种可能性
你说 C 代码中的字符串是 wstring aka. 基于 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"*/);
然而
std::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("UTF8")
- 为什么我在蓝牙连接()上收到"java.io.IOException:读取失败,套接字可能关闭或超时,读取re
- Java 套接字读取在第二次读取时返回奇怪字符
- 无法在java(客户端)的套接字上正确写入数据(类),也无法在c ++(服务器)上读取数据(类)
- Java 服务器套接字,客户端采用 C 语言
- 通过套接字将 Mat 对象从 c++ 发送到 Java
- JAVA:我无法从套接字读取文本,通过C++程序发送
- 套接字Java到C++-消息的长度总是8192个字符
- c++套接字客户端在输出流关闭的情况下不断从Java服务器事件中接收一些内容
- Windows中Java和C之间的任何IPC机制 - 不需要套接字
- Java -> C++ TCP 套接字直到关闭才发送
- UDP 数据报套接字编程,服务器在 JAVA 中,客户端在 C++
- C++套接字 - wstring 到 Java 套接字
- 如何通过套接字C++服务器/Java客户端发送int
- 使用来自C++的 java 套接字接收浮点数
- 套接字 - Java 未以正确的编码接收字节
- Java中的缓冲流和C++中使用套接字的区别
- TCP 套接字连接 Java 客户端<-> c++ 服务器中的意外行为
- 如何通过套接字将double或任何其他随机类型从Java传递到C++
- 通过套接字从Java向CPP发送屏幕截图-发出接收图像
- 需要帮助java到C++的ssl套接字