socket

bnuf 2011-06-15 12:54:33
我的程序是一个基于socket的即时群聊系统

客户端和服务器socket都是用utf-8编码。客户端和服务器在同一台机器上测试的时候,完全正常。当分开时,客户端本来应该收到hello这个单词,现在却多收到了两个字符 \ufffd\ufffd

eclipse中编译时设置了utf-8.

谁有同样的问题啊,求救。。
...全文
169 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
bnuf 2011-06-16
  • 打赏
  • 举报
回复
去掉SendUrgentData的使用,自己定义一个心跳消息让客户端回应。
http://topic.csdn.net/u/20100311/21/3624065c-ef95-4569-93f0-622cdcaed4b2.html
看上面这个吧,遇到的是同样的问题,具体原因还没找出来。
[Quote=引用 20 楼 qybao 的回复:]

怎么解决的?
[/Quote]
qybao 2011-06-16
  • 打赏
  • 举报
回复
怎么解决的?
bnuf 2011-06-16
  • 打赏
  • 举报
回复
谢谢,问题解决了
http://topic.csdn.net/u/20100311/21/3624065c-ef95-4569-93f0-622cdcaed4b2.html
哎,不知道具体原因。

[Quote=引用 17 楼 qybao 的回复:]

你试试看取到数据后把它转为系统编码看看
Java code
for example
String s = br.readLine();
s = new String(s.getByte("UTF-8"));
[/Quote]
bnuf 2011-06-15
  • 打赏
  • 举报
回复
服务端发送的消息是:

pw.println("hello");
pw.flush();
bnuf 2011-06-15
  • 打赏
  • 举报
回复
这是服务端的流:
OutputStreamWriter stream = new OutputStreamWriter(
socket.getOutputStream(), "UTF8");
pw = new PrintWriter(stream);
br = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "UTF8"));
这是客户端的流:
BufferedReader br = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream(), "UTF-8"));

OutputStreamWriter stream = new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8");
xiongjingjing58 2011-06-15
  • 打赏
  • 举报
回复
我对套接字不太了解,帮忙第一下哈
qybao 2011-06-15
  • 打赏
  • 举报
回复
你试试看取到数据后把它转为系统编码看看
for example
String s = br.readLine();
s = new String(s.getByte("UTF-8"));
qybao 2011-06-15
  • 打赏
  • 举报
回复
你试试看取到数据后把它转为系统编码看看
for example
String s = br.readLine();
s = new String(s.getByte("UTF-8"));
bnuf 2011-06-15
  • 打赏
  • 举报
回复
谢谢你仔细的回答~
我使用BufferedReader的readline来读数据的,我跟踪到方法里面发现每次readline都会读到\ufffd到数组最后(\r\n后面),只不过第一次OK可以直接输出。
我目前传输的都是英文串,为什么会有乱码问题啊?
有人说可能是不同jre之间传输信息需要BOM,不知道是不是,继续等待解决方法。
[Quote=引用 14 楼 qybao 的回复:]

在网上查了一下

中文转码时'?'、乱码的由来

两个方向转换都有可能得到错误的结果:

•Unicode-->Byte, 如果目标代码集不存在对应的代码,则得到的结果是 0x3f.
如:
"\u00d6\u00ec\u00e9\u0046\u00bb\u00f9".getBytes("GBK") 的结果是 "? ìé F? ù", Hex 值是 3fa8aca8a6463f……
[/Quote]
qybao 2011-06-15
  • 打赏
  • 举报
回复
在网上查了一下

中文转码时'?'、乱码的由来

两个方向转换都有可能得到错误的结果:

•Unicode-->Byte, 如果目标代码集不存在对应的代码,则得到的结果是 0x3f.
如:
"\u00d6\u00ec\u00e9\u0046\u00bb\u00f9".getBytes("GBK") 的结果是 "? ìé F? ù", Hex 值是 3fa8aca8a6463fa8b4.

仔细看一下上面的结果,你会发现 \u00ec 被转换为 0xa8ac, \u00e9 被转换为 \xa8a6... 它的实际有效位变长了!这是因为 GB2312 符号区中的一些符号被映射到一些公共的符号编码,由于这些符号出现在 ISO-8859-1 或其它一些 SBCS 字符集中,故它们在 Unicode 中编码比较靠前,有一些其有效位只有 8 位,和汉字的编码重叠 ( 其实这种映射只是编码的映射,在显示时仔细不是一样的。Unicode 中的符号是单字节宽,汉字中的符号是双字节宽 ) . 在 Unicode\u00a0--\u00ff 之间这样的符号有 20 个。了解这个特征非常重要!由此就不难理解为什么 JAVA 编程中,汉字编码的错误结果中常常会出现一些乱码 ( 其实是符号字符 ), 而不全是'?'字符 , 就比如上面的例子。

•Byte-->Unicode, 如果 Byte 标识的字符在源代码集不存在,则得到的结果是 0xfffd.
如:
Byte ba[] = {(byte)0x81,(byte)0x40,(byte)0xb0,(byte)0xa1}; new String(ba,"gb2312");

结果是"? 啊", hex 值是"\ufffd\u554a". 0x8140 是 GBK 字符,按 GB2312 转换表没有对应的值,取 \ufffd. ( 请注意:在显示该 uniCode 时,因为没有对应的本地字符,所以也适用上一种情况,显示为一个"?".)

UTF-8是变字节长度的,最多3个字节,最少一个字节,所以UTF-8编码传输时,如果接收方还原字符串时,存在无法识别的byte,根据上面的第二处红色部分的说明,可能就会转为 \ufffd了
LZ的客户端是怎么read数据流的?
bnuf 2011-06-15
  • 打赏
  • 举报
回复
我发现好像只有第一次得到的字符串不含\ufffd,其他后面得到的都含有数量不等的\ufffd。难道是printwriter写入然后flash会留下什么东西?我的程序不是命令行的,是swing里面的,目前接收到的字符串都是服务端代码里面的长量串。
[Quote=引用 12 楼 qybao 的回复:]

引用 7 楼 bnufq 的回复:
还有很重要的一点,我的OK和hello这两个字符串都是写在源码里面的,源码的编码是UTF-8,eclipse中设置正确。我查了一下,发送英文应该不会出现乱码啊,而且第一个OK正确发送。

谢谢各位的回复,希望有人知道问题所在。

我觉得这可能是显示的问题,你在同一台机器是如何测试的?在别的机器上的客户端,它的控制台本身是UTF-8的吗?如果不是,可能……
[/Quote]
qybao 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bnufq 的回复:]
还有很重要的一点,我的OK和hello这两个字符串都是写在源码里面的,源码的编码是UTF-8,eclipse中设置正确。我查了一下,发送英文应该不会出现乱码啊,而且第一个OK正确发送。

谢谢各位的回复,希望有人知道问题所在。
[/Quote]
我觉得这可能是显示的问题,你在同一台机器是如何测试的?在别的机器上的客户端,它的控制台本身是UTF-8的吗?如果不是,可能会乱码的。
qybao 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bnufq 的回复:]
还有很重要的一点,我的OK和hello这两个字符串都是写在源码里面的,源码的编码是UTF-8,eclipse中设置正确。我查了一下,发送英文应该不会出现乱码啊,而且第一个OK正确发送。

谢谢各位的回复,希望有人知道问题所在。
[/Quote]
我觉得这可能是显示的问题,你在同一台机器是如何测试的?在别的机器上的客户端,它的控制台本身是UTF-8的吗?如果不是,可能会乱码的。
php17 2011-06-15
  • 打赏
  • 举报
回复
建议楼主把OutputStreamWriter stream = new OutputStreamWriter(
socket.getOutputStream(), "UTF8");改为OutputStreamObject stream = new OutputStreamObject(
socket.getOutputStream());接收流也相应修改,接收时你发送是什么类型,接收就转换为什么类型,一切就ok了。。。
bnuf 2011-06-15
  • 打赏
  • 举报
回复
还有很重要的一点,我的OK和hello这两个字符串都是写在源码里面的,源码的编码是UTF-8,eclipse中设置正确。我查了一下,发送英文应该不会出现乱码啊,而且第一个OK正确发送。

谢谢各位的回复,希望有人知道问题所在。
安特矮油 2011-06-15
  • 打赏
  • 举报
回复
没遇到过,帮你顶一下
bnuf 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qybao 的回复:]

送信时试试改下字符串的编码
比如原来的送信是
pw.println("hello");
pw.flush();

改成
pw.println(new String("hello".getByte("UTF-8"), "UTF-8"));
pw.flush();
[/Quote]
还是不行,本机测试一切都正常,放到服务器上第二次返回的结果就多了两个字符。
第一次正常返回一个字符串 OK
第二次返回 \ufffd\ufffdhello
两次都是用println然后flush
qybao 2011-06-15
  • 打赏
  • 举报
回复
送信时试试改下字符串的编码
比如原来的送信是
pw.println("hello");
pw.flush();

改成
pw.println(new String("hello".getByte("UTF-8"), "UTF-8"));
pw.flush();
bnuf 2011-06-15
  • 打赏
  • 举报
回复
那位好心人快帮一下忙啊,情况紧急

81,091

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧