[Socket 小白求助]socket read 服务器返回 unknown length - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
haosamax
V2EX    Java

[Socket 小白求助]socket read 服务器返回 unknown length

  •  
  •   haosamax 2021 年 2 月 1 日 2207 次点击
    这是一个创建于 1815 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以前基本不写 Socket,都是调包侠。现在这个项目 socket 通讯,约定前六位是后面数据包长度(不够左补 0),后面是数据包,像这样:000length|xxxxxxxxxxxxxxxxxxxxx,求教,socket.read 怎么读,我是先读 6 位,算出 length,再读 length吗?

    14 条回复    2021-02-01 14:50:49 +08:00
    Edsie
        1
    Edsie  
       2021 年 2 月 1 日
    char[6]读取前 6 个,解析出 length,再读后面的
    haosamax
        2
    haosamax  
    OP
       2021 年 2 月 1 日
    @Edsie send 的时候要发送两次吗,第一次发送,读 length,第二次发送读后面的
    ScepterZ
        3
    ScepterZ  
       2021 年 2 月 1 日
    @haosamax 发送随便怎么发都行,反正是流
    haosamax
        4
    haosamax  
    OP
       2021 年 2 月 1 日
    @ScepterZ 这个后面 xxx 部分是 json 字符串比较烦,其他的都是传的 k-v,我们约定只对 v 编码传输,指定长度、填充字符、填充位置,这样我可以 read(b),b 可以指定已知长度根据接口文档。像这种不知道长度的比如 json,或者 xxx 含有循环体,我看别人写的都是创建两个 socket,发送两次,第一次获取 length,第二次获取读后面的,两次建立连接,这不影响性能吗
    LGA1150
        5
    LGA1150  
       2021 年 2 月 1 日 via Android
    @Edsie 一个 char 占两字节
    Kamiyu0087
        6
    Kamiyu0087  
       2021 年 2 月 1 日
    先问问前六位表示数据包长度指的是 6 个 bit 还是 6 个 byte?
    如果是 byte,很好奇要传啥数据需要定那么大的长度?
    如果是 bit,那第一个字节的最后两个 bit 是空置还是直接跟上后续数据包的数据?
    zlwen
        7
    zlwen  
       2021 年 2 月 1 日
    用 netty
    haosamax
        8
    haosamax  
    OP
       2021 年 2 月 1 日
    @Kamiyu0087 6byte 。十进制的,最多 byte[999999],还行吧
    @zlwen 计划下个版本就接入 netty
    haosamax
        9
    haosamax  
    OP
       2021 年 2 月 1 日
    @haosamax 这个半吊子自定义协议,循环体处理就这
    Kamiyu0087
        10
    Kamiyu0087  
       2021 年 2 月 1 日
    @haosamax 那 3 个字节就够了啊,为啥要 6 个字节
    不会是每个字节就 0 ~ 9,然后转字符串拼接吧? - -!
    haosamax
        11
    haosamax  
    OP
       2021 年 2 月 1 日
    @Kamiyu0087 sry,我搞错了,是 6 个字节,不是 999999...。为什么这么大,我也不知道,平台约定的
    haosamax
        12
    haosamax  
    OP
       2021 年 2 月 1 日
    @Kamiyu0087 还是指定长度 6 位的字符串拉
    LGA1150
        13
    LGA1150  
       2021 年 2 月 1 日
    #11 #12 长度到底是 ASCII 还是二进制?
    如果是 ASCII,读到 byte[]里,转 String 再转 int
    byte[] buf = new byte[6];
    inputStream.read(buf);
    int length = Integer.parseInt(new String(buf));
    如果是二进制,读到 byte[]里,转 BigInteger 再转 long
    byte[] buf = new byte[7]; // 多分配一个字节保证转换为正数
    inputStream.read(buf, 1, 6);
    long length = new BigInteger(buf).longValue();
    Edsie
        14
    Edsie  
       2021 年 2 月 1 日
    盲猜是六个字符,最好确认一下

    send 的时候也不需要发两次,基于流的 IO 没道理发两次。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     995 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 22:09 PVG 06:09 LAX 14:09 JFK 17:09
    Do have faith in what you're doing.
    ubao msn 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