weixin_45661471 2022-09-02 18:19 采纳率: 72.7%
浏览 766
已结题

客户端使用protobuf协议,服务端用java接收的时候一直报Protocol message contained an invalid tag (zero).

问题遇到的现象和发生背景

客户端使用protobuf协议,服务端用java接收的时候一直报Protocol message contained an invalid tag (zero).

问题相关代码,请勿粘贴截图

客户端的消息发送成功了

img

服务端报错内容

img

io.netty.handler.codec.DecoderException: com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:425)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Caused by: com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).
at com.google.protobuf.InvalidProtocolBufferException.invalidTag(InvalidProtocolBufferException.java:133)
at com.google.protobuf.CodedInputStream$ArrayDecoder.readTag(CodedInputStream.java:633)
at com.ma.mhxy.protobuf.Message$NetMessage.(Message.java:298)
at com.ma.mhxy.protobuf.Message$NetMessage.(Message.java:261)
at com.ma.mhxy.protobuf.Message$NetMessage$1.parsePartialFrom(Message.java:1030)
at com.ma.mhxy.protobuf.Message$NetMessage$1.parsePartialFrom(Message.java:1024)
at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:158)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:191)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:197)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:48)
at io.netty.handler.codec.protobuf.ProtobufDecoder.decode(ProtobufDecoder.java:119)
at io.netty.handler.codec.protobuf.ProtobufDecoder.decode(ProtobufDecoder.java:66)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)

C# 使用的Message的proto文件

syntax = "proto3";

package SkillBridge.Message;

option csharp_namespace = "SkillBridge.Message";

option cc_enable_arenas = true;

////////////////////////////////////////////////////////////////
//
// Basic Defines
//
////////////////////////////////////////////////////////////////
enum RESULT
{
SUCCESS = 0;
FAILED = 1;
}

enum CHARACTER_CLASS
{
NONE = 0;
}

////////////////////////////////////////////////////////////////
//
// Messages
//
////////////////////////////////////////////////////////////////

message NetMessage{
NetMessageRequest Request = 1;
NetMessageResponse Response = 2;
}

message NetMessageRequest{
UserRegisterRequest userRegister = 1;
UserLoginRequest userLogin = 2;
UserCreateCharacterRequest createChar = 3;

}

message NetMessageResponse{
UserRegisterResponse userRegister = 1;
UserLoginResponse userLogin = 2;
UserCreateCharacterResponse createChar = 3;

}

// User Protocol
message UserLoginRequest {
string user = 1;
string passward = 2;
}

message UserLoginResponse {
RESULT result = 1;
string errormsg = 2;
NUserInfo userinfo = 3;
}

message UserRegisterRequest
{
string user = 1;
string passward = 2;
}

message UserRegisterResponse {
RESULT result = 1;
string errormsg = 2;
}

message UserCreateCharacterRequest
{
string name = 1;
CHARACTER_CLASS class = 2;
}

message UserCreateCharacterResponse {
RESULT result = 1;
string errormsg = 2;
repeated NCharacterInfo characters = 3;
}

message NUserInfo {
int32 id = 1;
NPlayerInfo player = 2;
}

message NPlayerInfo {
int32 id = 1;
repeated NCharacterInfo characters = 2;
}

message NCharacterInfo {
int32 id = 1;//db id
int32 config_id = 2;//config id
int32 entity_id = 3;//entity id
string name = 4;
int32 level = 7;
int32 mapId = 8;
int64 gold = 10;
int32 ride = 17;
}

message NEntity {
int32 id = 1;
NVector3 position = 2;
NVector3 direction = 3;
int32 speed = 4;
}

message NVector3
{
int32 x = 1;
int32 y = 2;
int32 z = 3;
}

java使用的proto文件__

// 声明使用proto3
syntax = "proto3";
// 包名
option java_package = "com.ma.mhxy.protobuf";
// 类名
option java_outer_classname = "Message";

enum RESULT
{
SUCCESS = 0;
FAILED = 1;
}

enum CHARACTER_CLASS
{
NONE = 0;
}

////////////////////////////////////////////////////////////////
//
// Messages
//
////////////////////////////////////////////////////////////////

message NetMessage{
NetMessageRequest Request = 1;
NetMessageResponse Response = 2;
}

message NetMessageRequest{
UserRegisterRequest userRegister = 1;
UserLoginRequest userLogin = 2;
UserCreateCharacterRequest createChar = 3;

}

message NetMessageResponse{
UserRegisterResponse userRegister = 1;
UserLoginResponse userLogin = 2;
UserCreateCharacterResponse createChar = 3;

}

// User Protocol
message UserLoginRequest {
string user = 1;
string passward = 2;
}

message UserLoginResponse {
RESULT result = 1;
string errormsg = 2;
NUserInfo userinfo = 3;
}

message UserRegisterRequest
{
string user = 1;
string passward = 2;
}

message UserRegisterResponse {
RESULT result = 1;
string errormsg = 2;
}

message UserCreateCharacterRequest
{
string name = 1;
CHARACTER_CLASS class = 2;
}

message UserCreateCharacterResponse {
RESULT result = 1;
string errormsg = 2;
repeated NCharacterInfo characters = 3;
}

message NUserInfo {
int32 id = 1;
NPlayerInfo player = 2;
}

message NPlayerInfo {
int32 id = 1;
repeated NCharacterInfo characters = 2;
}

message NCharacterInfo {
int32 id = 1;//db id
int32 config_id = 2;//config id
int32 entity_id = 3;//entity id
string name = 4;
int32 level = 7;
int32 mapId = 8;
int64 gold = 10;
int32 ride = 17;
}

message NEntity {
int32 id = 1;
NVector3 position = 2;
NVector3 direction = 3;
int32 speed = 4;
}

message NVector3
{
int32 x = 1;
int32 y = 2;
int32 z = 3;
}

这个是c#服务器的正常解析代码
///


/// 数据包解析
///

///
bool ParsePackage()
{
if (readOffset + 4 < stream.Position)
{
int packageSize = BitConverter.ToInt32(stream.GetBuffer(), readOffset);
if (packageSize + readOffset + 4 <= stream.Position)
{//包有效

                SkillBridge.Message.NetMessage message = UnpackMessage(stream.GetBuffer(), this.readOffset + 4, packageSize);
                if (message == null)
                {
                    throw new Exception("PackageHandler ParsePackage faild,invalid package");
                }
                MessageDistributer<T>.Instance.ReceiveMessage(this.sender, message);
                this.readOffset += (packageSize + 4);
                return ParsePackage();
            }
        }

        //未接收完/要结束了
        if (this.readOffset > 0)
        {
            long size = stream.Position - this.readOffset;
            if (this.readOffset < stream.Position)
            {
                Array.Copy(stream.GetBuffer(), this.readOffset, stream.GetBuffer(), 0, stream.Position - this.readOffset);
            }
            //Reset Stream
            this.readOffset = 0;
            stream.Position = size;
            stream.SetLength(size);
        }
        return true;
    }

是c#的解包的代码,c#这边是能正常收发数据,是不是java需要一个自定义解码器

我想要达到的结果

不知道为什么,后端解码一直报错,有大佬能帮解答下吗?

  • 写回答

3条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 9月10日
  • 修改了问题 9月4日
  • 赞助了问题酬金10元 9月4日
  • 创建了问题 9月2日

悬赏问题

  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容