用protobuf数据格式,报“Protocol message tag had invalid wire type”异常
因为业务需要,把原本的json的传输格式改成protobuf。服务端这边用的是php,客户端那边是android和ios。
在调试的过程中,发现客户端一直不能解析服务端传输过去的数据,android客户端一直报异常,如下:
Protobuf error:Protocol message tag had invalid wire type
背景信息
php端这边的情况
- php5.4
- Porobuf-php
- protoc 2.4.1
- mac osx 10.8下开发
Android端
- Android版本4.4
- 官方的protobuf库 2.4.1
- protoc 2.4.1
- ubuntu
php和android都是用同一套*.proto文件去生成对应的类。
php这边是如下序列化的:
// use binary codec
$codec = new \DrSlump\Protobuf\Codec\Binary();
// prepare final output
$response = new \ResponseMsg();
$response->setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
$response->setData($codec->encode($recommend_bras));
// Use custom codec
$data = $codec->encode($response);
echo $data;
Android端的反序列化:
byte[] bytes = ret.result.getBytes();
//ByteString byteString = ByteString.copyFromUtf8(ret.result);
PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes);
回复内容:
Hi,all
因为业务需要,把原本的json的传输格式改成protobuf。服务端这边用的是php,客户端那边是android和ios。
在调试的过程中,发现客户端一直不能解析服务端传输过去的数据,android客户端一直报异常,如下:
Protobuf error:Protocol message tag had invalid wire type
背景信息
php端这边的情况
- php5.4
- Porobuf-php
- protoc 2.4.1
- mac osx 10.8下开发
Android端
- Android版本4.4
- 官方的protobuf库 2.4.1
- protoc 2.4.1
- ubuntu
php和android都是用同一套*.proto文件去生成对应的类。
php这边是如下序列化的:
// use binary codec
$codec = new \DrSlump\Protobuf\Codec\Binary();
// prepare final output
$response = new \ResponseMsg();
$response->setStatusCode(\ResponseMsg\ErrorCode::RET_OK);
$response->setData($codec->encode($recommend_bras));
// Use custom codec
$data = $codec->encode($response);
echo $data;
Android端的反序列化:
byte[] bytes = ret.result.getBytes();
//ByteString byteString = ByteString.copyFromUtf8(ret.result);
PResponseMsg.ResponseMsg responseMsg = PResponseMsg.ResponseMsg.parseFrom(bytes);
找到解决方法了,把传输的内容用base64编码再传输就可以了。
同事提示用二分法去查找问题,所以我做了下面的尝试:
1、先把服务器序列化后的内容存到内存,然后反解,发现没问题。初步猜想可能是内容在传输的过程中出了问题。因为客户端和服务端之间是用http传输的,可能是内容编码格式有问题。
2、让客户端的同事帮忙把收到的内容存到文件系统,然后对比服务端的内容,确认是不是存在编码问题。最后发现,两者的内容长度不一样,确认是传输过程中出了问题。
3、查了下网上的一些说法,二进制的内容不能直接在http协议传输,于是该用base64编码之后再传输出去,客户端拿到再反解,能拿到最后的数据了。
暂时还没想到为什么用protobuf-php库把内容序列化后,再传输为什么会不行,待补充......
下一篇: Python中多线程及程序锁浅析