Java Socket 客户端读出问题了

2020-04-24 16:29:10 +08:00
 likefly
// 往服务端写
write(param);

TimeUnit.SECONDS.sleep(1);

// 读取服务端返回的数据
String data = read(param);

如果中间的休眠去掉,有很大几率直接读取返回的数据会出现数据丢失,有可能只读了一半。


read 方法代码大概是这样

InputStream is
// 先读八个字节
byte[] header= new byte[8];
is.read(header);

// 转换成字符串之后再转换成整数
int length = Integer.valueOf(new String(header));
// 读取正文
byte[] content = new byte[length];
is.read(content);
1373 次点击
所在节点    程序员
5 条回复
twoconk
2020-04-24 17:52:00 +08:00
是有点诡异,通常网络请求是一个阻塞的,如果不是异步 IO,通常是在单独的线程中循环读,类似下面的代码:


byte[] buffer= new byte[1024*10];
while(1){
int len=is.read(buffer);
//业务在这里实现

TimeUnit.SECONDS.sleep(1);
}
23571113
2020-04-24 18:59:24 +08:00
用粘包警察的话来说就是粘包了
opengps
2020-04-24 19:04:47 +08:00
通常都是粘包问题,不前后拼接拿不到完整的。
解决方案,要么处理粘包,要么设计成带回复的通信协议,不回复主动重发
djoiwhud
2020-04-24 19:48:51 +08:00
第一,代码要给全,不想泄露业务就自己弄个福利的测试用例。
第二,应该所有语言的 tcp 协议的 read 都会返回读取的实际长度。你这里压根没处理。
第三,你应该用 nio,streambuffer 这类处理,不是 java 开发,仅仅写过 java 适配的网络模块。可能有不对的地方。
第四,网络本身并不是阻塞的。不同语言,处理方式有差异。有些语言可以设置读超时,超时后继续下一个读轮训。
qumingkunnan
2020-04-25 13:58:47 +08:00
tcp 一直读,读到什么时候算结束应该由你的协议来定

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/665729

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX