协议格式:
1.uint16 消息长度 msgLen,下面的 2,3,4 的总 byte 长度,不包括 msgLen 本身,2,3,4 统称为 msgData
2.uint8 校验字段,算法如下:
发送的时候:
var cbCheckCode byte=0
for i = 1; i < msgLen; i++ {
cbCheckCode += msgData[i]
}
result = ^cbCheckCode + 1//然后把结果 result 写入 uint8 校验字段 msgData[0]
接收的时候:
var cbCheckCode byte=msgData[0]
for i = 1; i < msgLen; i++ {
cbCheckCode += msgData[i]
}
if 0 != cbCheckCode {
return//校验结果有误,报错
}
消息数据:
3.uint32 消息号:uint32(mainCmdID) | uint32(subCmdID)<<16,mainCmdID (主消息号)和 subCmdID (子消息号)都是 uint16
4.byte 字节流,消息数据 data,一般是 struct 的结构体数据转换成字节流,到时候看具体用到的数据类型再说怎么转换,比如 string 类型,转换成字节流的话,前面 2 个字节表示长度,后面的就是 string 的内容
1
tearslee OP 我是做 javaWeb 的,对于校验 tcp 校验不是很明白,请教一下各位,我该如何写编解码器?
|
2
xzg 2019-02-25 10:59:11 +08:00
这是 java ?这是 go 的代码吧。还有计算 cbCheckCode 又放到 msgData[0]里看不懂。我觉得如果校验发送数据可以用 bcc 校验码添加到字节流的末尾,接收数据再取末尾校验。
|
3
coolcfan 2019-02-25 11:02:16 +08:00
发送 /接受的格式是别人定义的还是需要自己定义?
如果是别人定义的,那自己画个图把数据包格式画出来,程序里按顺序读写就行了…… |
4
SilentHill 2019-02-25 11:06:54 +08:00
没看懂啊。。这和 tcp 有啥关系?而且你做 web 的,还有自己代码接收网络数据的需求?
而且 java 没有 struct 啊,这语法看着也不像 java。 如果自己定义数据格式,那么对于服务端,就一直尝试读取期望的字节大小,读到报文头后,解析出来,得到数据长度后,在继续读取期望的大小,多余的丢掉,最后反序列化为内部可识别的结构体或者类。。 至于序列化和反序列化,为什么不用已经很成熟的 google protobuf,而自己去编解码呢。。 |
5
tearslee OP @SilentHill 就是 socket 通信问题,我的后台与服务器需要使用 socket 通信, 协议是对方定义的,我需要对接.
|
8
SilentHill 2019-02-25 11:18:19 +08:00
@tearslee
那就是 socket 编程喽,其实这个网上还是挺多的,基本代码样例都差不多。和我上面说的差不多,因为报文格式和大小都是严格确定的,所以在服务端一直读到期望的大小再进行反序列化,具体可以在网上找找,这里一言两句说不清的,而且你这个也不是 java |
9
coolcfan 2019-02-25 11:27:46 +08:00 1
@tearslee #7
先把格式画出来嘛, | length: 2 | checksum: 1 | id: 4 | payload: [ length: 2 | content: length ] | 按照顺序把 byte 读进来就行了,你把除了“ content ”的部分都当作 header,相当于 header 一共 9 个 byte,后面读多少按照 header 提供的信息去读 |
11
buliugu 2019-02-25 11:41:33 +08:00
如果使用 netty,请看一下 Decoder
|
13
honeycomb 2019-02-25 11:48:18 +08:00 via Android
@tearslee 比较笨但也简单的一个办法是用 netty 的套路写收发消息的组件,然后自己做一个 Decoder 的实现,它给的输入直接包装成了 netty 的 ByteBuf,这东西比 Java 自己的 ByteBuffer 好用。
之后校验,反序列化(到一个 Java pojo )都能轻松地在里面做了。 |
14
honeycomb 2019-02-25 11:50:22 +08:00 via Android
@tearslee 客户端的话也可利用 netty 的 bytebuf 组件来简化处理 byte 数组
|
15
blackboom 2019-02-25 11:53:24 +08:00
没有仔细看,你的问题是什么呢,校验结果有误,报错?
Netty io.netty.handler.codec.protobuf 包中有这么两个类 ProtobufVarint32LengthFieldPrepender ProtobufVarint32FrameDecoder |
18
ZiLong 2019-02-25 15:44:15 +08:00
还是要看你用的什么通信模型,bio/bio 及使用类库(jdk/netty/mina),调用相应读取接口
|