我手边的问题是要让一个Java程序和一个C++程序进行socket通讯.
C++部分是通过iostream来输入输出字符串的.
Java部分是通过in/outputStream来传值.
从C++传递string去Java没有问题,
可以从Java部分传递string去C++部分则有问题. 我的Java程序是这通过String.getBytes()来取得String的byte 数组.
然后把bytes通过outputStream写入socket的.
例如我要写一个字符串"abcd", 现在C++部分接收到的字符串是"abcd\377\377\377\377\037"
多出来的部分不知道是哪里来的. 在Java部分, "abcd".getBytes().size()是4.
到了C++端, string.size()则是比实际长度大很多. 目前我的怀疑是因为Java的字符串编码是utf-8的, 而C++则是ascii码, 所以有问题.
但是我也试过"abcd".getBytes("ASCII"), 但问题依旧. 多谢!
C++部分是通过iostream来输入输出字符串的.
Java部分是通过in/outputStream来传值.
从C++传递string去Java没有问题,
可以从Java部分传递string去C++部分则有问题. 我的Java程序是这通过String.getBytes()来取得String的byte 数组.
然后把bytes通过outputStream写入socket的.
例如我要写一个字符串"abcd", 现在C++部分接收到的字符串是"abcd\377\377\377\377\037"
多出来的部分不知道是哪里来的. 在Java部分, "abcd".getBytes().size()是4.
到了C++端, string.size()则是比实际长度大很多. 目前我的怀疑是因为Java的字符串编码是utf-8的, 而C++则是ascii码, 所以有问题.
但是我也试过"abcd".getBytes("ASCII"), 但问题依旧. 多谢!
这里的问题是getBytes()得到的字节数组不是零字符结尾的,所以构造string时就会多出后面的字符,并以一个随机的零字符位置结束。解决的办法是从Java向传输时,在最后加一个0字节;或者在传输字符串之前,传输字符串长度,再做相应处理。 PS:C++的默认字符编码在中文Windows系统上一般是GBK。
但是我不清楚你所说的末尾加0字节,应该是怎么操作?
我试了代码如下: public void writeString(String S) throws IOException{
byte[] bytes;
bytes = S.getBytes();
OS.write(bytes);
OS.write((byte)0); //或是: OS.write('\0);
}
但还是不可以. 传送过去的字符串还是超长.
调用过writeString后, 即会调用OS.flush().
应该此字符串后, 应该没有别的字符了.
一开始我采用yinjintao所建议的第二种方式, 首先传输字符串长度的方法.
但后来我发现, 这样做的话, 会影响到后续socket的读取. 似乎有部分二进制的数据仍然存储在socket的buffer里, 从而导致后续读取二进制数据时会存在问题. 后来发现, 因为我在C++端是采用std::getline来取string, 因此字符串末尾需要添加'\n'来标识字符串尾的. 一开始我采用的方式是(string + '\n').getBytes(), 但是仍无法截断. 所以现在采用的是这样的代码: public void writeString(String S) throws IOException{
byte[] bytes;
bytes = S.getBytes();
OS.write(bytes);
OS.write((byte)'\n');
}
现在就ok了.