求教一个 Java 流数据读取的问题

1 天前
 dumbbell5kg

问题背景 是对方响应了较长的返回报文,长度是 9.7 万字节,我这边作为接受方调用 SocketInputStream 的 available 方法来判断可读大小是否到达了 9.7 。

测试下来,在其中一台 linux 上 available 方法立即返回了 9.7w 的长度。而另一台 linux 始终只能返回 68176 。

想请教导致这种差异的原因是什么,我该怎么让另一台机器也达到 9.7w 的长度?

824 次点击
所在节点    程序员
13 条回复
sujin190
1 天前
缓冲区不一样呗,就本来就没说全接收到内存中吧,本来就不可以像你说的这样用
night98
1 天前
这个不是应该读完之后再判断长度够不够吗,你说的这个问题,合理怀疑应该是 linux 网络缓冲区的配置差异问题或者网卡的缓冲区配置问题。理论上最好是读完再判断长度。
zhuangzhuang1988
23 小时 58 分钟前
流式协议不要预设长度。
dumbbell5kg
23 小时 30 分钟前
@night98 报文前几位是长度,我这边拿到长度,再等到 available 返回值达到指定长度再读取数据
night98
23 小时 25 分钟前
@dumbbell5kg #4 流不是这么玩的吧,你应该拿到长度之后一直读,直到读到报文指定长度之后就开始你的业务处理就行了。
dumbbell5kg
23 小时 23 分钟前
@sujin190 对的,这个问题只要我重复从读取流就行了,但是它是老代码,我现在还没法让他们信任我去改公共代码
dumbbell5kg
23 小时 22 分钟前
@night98 哈哈,是的,挺离谱的,老代码,算了,我新业务不用他们的老代码好了。。
sagaxu
23 小时 19 分钟前
完全没学过计算机网络?你这思想很危险,你应该一有数据就读,自己维护一个 buffer ,把读到的数据 append 进去,够长度了就整个完整报文丢给业务中的下一层逻辑去处理。如果你一直不读,发送方可能还会阻塞在那边无法继续发送。
sujin190
23 小时 1 分钟前
@dumbbell5kg 公共库的话这算是比较低级的 bug 了,不让改也是。。
voidmnwzp
21 小时 2 分钟前
rb := make([]byte, 97000)
n, err := io.ReadFull(reader, rb)
这就是我转 go 的原因。。
wnpllrzodiac
21 小时 1 分钟前
tcp 就没边界,拿多少都有可能。
sagaxu
19 小时 27 分钟前
@voidmnwzp

// commons-io
byte[] buffer = new byte[100];
IOUtils.readFully(inputStream, buffer);

// guava
byte[] buffer = new byte[100];
ByteStreams.readFully(inputStream, buffer);

跟 io.ReadFull 有区别?
whp1473
10 小时 23 分钟前
不能这么玩吧,一般看里面嵌套的协议,比如先读取 32 位固定长度,获得后续报文的内容长度,获得完毕后解析。还有的是判断读取数据的标识符。还有是固定长度的。不能用缓冲大小判断

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

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

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

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

© 2021 V2EX