V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
dumbbell5kg
V2EX  ›  程序员

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

  •  
  •   dumbbell5kg · 14 小时 33 分钟前 · 595 次点击

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

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

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

    13 条回复    2024-12-26 09:55:56 +08:00
    sujin190
        1
    sujin190  
       14 小时 13 分钟前 via Android
    缓冲区不一样呗,就本来就没说全接收到内存中吧,本来就不可以像你说的这样用
    night98
        2
    night98  
       14 小时 7 分钟前
    这个不是应该读完之后再判断长度够不够吗,你说的这个问题,合理怀疑应该是 linux 网络缓冲区的配置差异问题或者网卡的缓冲区配置问题。理论上最好是读完再判断长度。
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       13 小时 55 分钟前
    流式协议不要预设长度。
    dumbbell5kg
        4
    dumbbell5kg  
    OP
       13 小时 27 分钟前
    @night98 报文前几位是长度,我这边拿到长度,再等到 available 返回值达到指定长度再读取数据
    night98
        5
    night98  
       13 小时 21 分钟前
    @dumbbell5kg #4 流不是这么玩的吧,你应该拿到长度之后一直读,直到读到报文指定长度之后就开始你的业务处理就行了。
    dumbbell5kg
        6
    dumbbell5kg  
    OP
       13 小时 20 分钟前
    @sujin190 对的,这个问题只要我重复从读取流就行了,但是它是老代码,我现在还没法让他们信任我去改公共代码
    dumbbell5kg
        7
    dumbbell5kg  
    OP
       13 小时 19 分钟前
    @night98 哈哈,是的,挺离谱的,老代码,算了,我新业务不用他们的老代码好了。。
    sagaxu
        8
    sagaxu  
       13 小时 15 分钟前   ❤️ 1
    完全没学过计算机网络?你这思想很危险,你应该一有数据就读,自己维护一个 buffer ,把读到的数据 append 进去,够长度了就整个完整报文丢给业务中的下一层逻辑去处理。如果你一直不读,发送方可能还会阻塞在那边无法继续发送。
    sujin190
        9
    sujin190  
       12 小时 58 分钟前 via Android
    @dumbbell5kg 公共库的话这算是比较低级的 bug 了,不让改也是。。
    voidmnwzp
        10
    voidmnwzp  
       10 小时 59 分钟前 via iPhone
    rb := make([]byte, 97000)
    n, err := io.ReadFull(reader, rb)
    这就是我转 go 的原因。。
    wnpllrzodiac
        11
    wnpllrzodiac  
       10 小时 58 分钟前 via Android
    tcp 就没边界,拿多少都有可能。
    sagaxu
        12
    sagaxu  
       9 小时 24 分钟前   ❤️ 1
    @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
        13
    whp1473  
       19 分钟前
    不能这么玩吧,一般看里面嵌套的协议,比如先读取 32 位固定长度,获得后续报文的内容长度,获得完毕后解析。还有的是判断读取数据的标识符。还有是固定长度的。不能用缓冲大小判断
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5978 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 02:15 · PVG 10:15 · LAX 18:15 · JFK 21:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.