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

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

  •  
  •   dumbbell5kg 290 天前 1816 次点击
    这是一个创建于 290 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题背景 是对方响应了较长的返回报文,长度是 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  
       290 天前 via Android
    缓冲区不一样呗,就本来就没说全接收到内存中吧,本来就不可以像你说的这样用
    night98
        2
    night98  
       290 天前
    这个不是应该读完之后再判断长度够不够吗,你说的这个问题,合理怀疑应该是 linux 网络缓冲区的配置差异问题或者网卡的缓冲区配置问题。理论上最好是读完再判断长度。
    zhuangzhuang1988
        3
    zhuangzhuang1988  
       290 天前
    流式协议不要预设长度。
    dumbbell5kg
        4
    dumbbell5kg  
    OP
       290 天前
    @night98 报文前几位是长度,我这边拿到长度,再等到 available 返回值达到指定长度再读取数据
    night98
        5
    night98  
       290 天前
    @dumbbell5kg #4 流不是这么玩的吧,你应该拿到长度之后一直读,直到读到报文指定长度之后就开始你的业务处理就行了。
    dumbbell5kg
        6
    dumbbell5kg  
    OP
       290 天前
    @sujin190 对的,这个问题只要我重复从读取流就行了,但是它是老代码,我现在还没法让他们信任我去改公共代码
        7
    dumbbell5kg  
    OP
       290 天前
    @night98 哈哈,是的,挺离谱的,老代码,算了,我新业务不用他们的老代码好了。。
    dumbbell5kg
    sagaxu
        8
    sagaxu  
       290 天前   1
    完全没学过计算机网络?你这思想很危险,你应该一有数据就读,自己维护一个 buffer ,把读到的数据 append 进去,够长度了就整个完整报文丢给业务中的下一层逻辑去处理。如果你一直不读,发送方可能还会阻塞在那边无法继续发送。
    sujin190
        9
    sujin190  
       290 天前 via Android
    @dumbbell5kg 公共库的话这算是比较低级的 bug 了,不让改也是。。
    voidmnwzp
        10
    voidmnwzp  
       290 天前 via iPhone
    rb := make([]byte, 97000)
    n, err := io.ReadFull(reader, rb)
    这就是我转 go 的原因。。
    wnpllrzodiac
        11
    wnpllrzodiac  
       290 天前 via Android
    tcp 就没边界,拿多少都有可能。
    sagaxu
        12
    sagaxu  
       289 天前   4
    @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  
       289 天前
    不能这么玩吧,一般看里面嵌套的协议,比如先读取 32 位固定长度,获得后续报文的内容长度,获得完毕后解析。还有的是判断读取数据的标识符。还有是固定长度的。不能用缓冲大小判断
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1564 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 16:32 PVG 00:32 LAX 09:32 JFK 12:32
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86