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