【问题标题】:Protobuf message exchange between plain TCP client & Netty Server using Java使用 Java 在普通 TCP 客户端和 Netty 服务器之间交换 Protobuf 消息
【发布时间】:2019-10-21 11:34:01
【问题描述】:

我正在尝试使用 Java 中的 Protobuf 消息交换格式在普通 TCP 客户端和 Netty 服务器之间创建 TCP 套接字连接,但它不起作用。当我使用 Netty 客户端(而不是 TCP 客户端)和 Netty 服务器时,它可以工作。

Netty Server 端,在 ServerHandler 类中,我将对象“msg”作为类型 “PooledUnsafeDirectByteBuf”。现在,当我尝试将其转换为我的自定义 Protobuf 对象时,它失败并出现错误 - 'java.lang.ClassCastException:类 io.netty.buffer.PooledUnsafeDirectByteBuf 无法转换为类 ProtoModel'。

public class ServerHandler extends ChannelInboundHandlerAdapter  {
---
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
--- 

客户端代码

Socket clientConnection = new Socket("localhost",SERVER_PORT);
ObjectOutputStream outToServer = new ObjectOutputStream(clientConnection.getOutputStream());
ProtoModel.writeTo(outToServer); //ProtoModel is the protobuf class

我认为这与 TCP 客户端的 Protobuf 消息编码和 Netty Server 端的解码有关。当我使用 Netty 客户端(而不是普通的 TCP 客户端)时,相同的服务器代码可以工作。

Netty 客户端代码

EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ClientInitializer());
Channel ch = bootstrap.connect("localhost",SERVER_PORT).sync().channel();
ChannelFuture lastWriteFuture = ch.writeAndFlush(ProtoModel);
lastWriteFuture.channel().closeFuture().sync();

如果我需要任何其他输入,请告诉我。非常感谢。

【问题讨论】:

    标签: java sockets tcp protocol-buffers netty


    【解决方案1】:

    我能够解决这个问题。我在下面发布解决方案。

    服务器代码

    public void channelRead(ChannelHandlerContext ctx, Object msg) {
                ByteBuf buf = (ByteBuf) msg;
                byte[] req = new byte[buf.readableBytes()];
                buf.readBytes(req);
                ProtobufModel obj = ProtobufModel.parseFrom(ByteString.copyFrom(req));
    }
    

    对象“msg”在服务器端以 ByteBuf 格式接收。然后需要将'ByteBuf'格式转换为'ByteString',最后可以从'ByteString'格式中检索ProtobufModel。

    客户端代码

    SocketChannel channel = SocketChannel
                        .open(new InetSocketAddress(InetAddress.getByName("localhost"), SERVER_PORT));
              ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
              byteBuffer.put(ProtobufModel.toByteArray());
              byteBuffer.flip();
              channel.write(byteBuffer);
    

    在客户端,ProtobufModel 被转换为 ByteBuffer 并传递给服务器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 2014-12-22
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多