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