问题背景 是对方响应了较长的返回报文,长度是 9.7 万字节,我这边作为接受方调用 SocketInputStream 的 available 方法来判断可读大小是否到达了 9.7 。
测试下来,在其中一台 linux 上 available 方法立即返回了 9.7w 的长度。而另一台 linux 始终只能返回 68176 。
想请教导致这种差异的原因是什么,我该怎么让另一台机器也达到 9.7w 的长度?
1
sujin190 1 天前 via Android
缓冲区不一样呗,就本来就没说全接收到内存中吧,本来就不可以像你说的这样用
|
2
night98 1 天前
这个不是应该读完之后再判断长度够不够吗,你说的这个问题,合理怀疑应该是 linux 网络缓冲区的配置差异问题或者网卡的缓冲区配置问题。理论上最好是读完再判断长度。
|
3
zhuangzhuang1988 1 天前
流式协议不要预设长度。
|
4
dumbbell5kg OP @night98 报文前几位是长度,我这边拿到长度,再等到 available 返回值达到指定长度再读取数据
|
5
night98 1 天前
@dumbbell5kg #4 流不是这么玩的吧,你应该拿到长度之后一直读,直到读到报文指定长度之后就开始你的业务处理就行了。
|
6
dumbbell5kg OP @sujin190 对的,这个问题只要我重复从读取流就行了,但是它是老代码,我现在还没法让他们信任我去改公共代码
|
7
dumbbell5kg OP @night98 哈哈,是的,挺离谱的,老代码,算了,我新业务不用他们的老代码好了。。
|
8
sagaxu 1 天前 1
完全没学过计算机网络?你这思想很危险,你应该一有数据就读,自己维护一个 buffer ,把读到的数据 append 进去,够长度了就整个完整报文丢给业务中的下一层逻辑去处理。如果你一直不读,发送方可能还会阻塞在那边无法继续发送。
|
9
sujin190 1 天前 via Android
@dumbbell5kg 公共库的话这算是比较低级的 bug 了,不让改也是。。
|
10
voidmnwzp 1 天前 via iPhone
rb := make([]byte, 97000)
n, err := io.ReadFull(reader, rb) 这就是我转 go 的原因。。 |
11
wnpllrzodiac 1 天前 via Android
tcp 就没边界,拿多少都有可能。
|
12
sagaxu 1 天前 3
@voidmnwzp
// commons-io byte[] buffer = new byte[100]; IOUtils.readFully(inputStream, buffer); // guava byte[] buffer = new byte[100]; ByteStreams.readFully(inputStream, buffer); 跟 io.ReadFull 有区别? |
13
whp1473 1 天前
不能这么玩吧,一般看里面嵌套的协议,比如先读取 32 位固定长度,获得后续报文的内容长度,获得完毕后解析。还有的是判断读取数据的标识符。还有是固定长度的。不能用缓冲大小判断
|