
以前基本不写 Socket,都是调包侠。现在这个项目 socket 通讯,约定前六位是后面数据包长度(不够左补 0),后面是数据包,像这样:000length|xxxxxxxxxxxxxxxxxxxxx,求教,socket.read 怎么读,我是先读 6 位,算出 length,再读 length吗?
1 Edsie 2021 年 2 月 1 日 char[6]读取前 6 个,解析出 length,再读后面的 |
4 haosamax OP @ScepterZ 这个后面 xxx 部分是 json 字符串比较烦,其他的都是传的 k-v,我们约定只对 v 编码传输,指定长度、填充字符、填充位置,这样我可以 read(b),b 可以指定已知长度根据接口文档。像这种不知道长度的比如 json,或者 xxx 含有循环体,我看别人写的都是创建两个 socket,发送两次,第一次获取 length,第二次获取读后面的,两次建立连接,这不影响性能吗 |
6 Kamiyu0087 2021 年 2 月 1 日 先问问前六位表示数据包长度指的是 6 个 bit 还是 6 个 byte? 如果是 byte,很好奇要传啥数据需要定那么大的长度? 如果是 bit,那第一个字节的最后两个 bit 是空置还是直接跟上后续数据包的数据? |
7 zlwen 2021 年 2 月 1 日 用 netty |
8 haosamax OP |
10 Kamiyu0087 2021 年 2 月 1 日 @haosamax 那 3 个字节就够了啊,为啥要 6 个字节 不会是每个字节就 0 ~ 9,然后转字符串拼接吧? - -! |
11 haosamax OP @Kamiyu0087 sry,我搞错了,是 6 个字节,不是 999999...。为什么这么大,我也不知道,平台约定的 |
12 haosamax OP @Kamiyu0087 还是指定长度 6 位的字符串拉 |
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(); |
14 Edsie 2021 年 2 月 1 日 盲猜是六个字符,最好确认一下 send 的时候也不需要发两次,基于流的 IO 没道理发两次。 |