0

Exploring nanopb client server example and trying with other protobuf library. My question is : Is nanopb generated protobuf compatible with protobuf generated in other language like java using google's protobuf-java ? protobuf encoded in nanopb can be decoded by google protobuf library in java and vice versa? I encountered a problem in socket communication between C protobuf client and Java Protobuf server. C client code follows nanopb network_server example, client server sharing same proto message. C client and C server is working fine , similarly Java client and Java Server is also working fine. However when C client connects to Netty TCP server it is not showing any output.

message Sample {
        optional string value = 1;
}

options has max_size defined.

C client code snippet :

  
  Sample message = Sample_init_default;        
  pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));        
  strcpy(message.value,"device1");
  status = pb_encode(&stream, Sample_fields, &message);        
  message_length = stream.bytes_written;                
  if (!status)
  {
            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));            
            return 1;
  }  
  pb_ostream_t output = pb_ostream_from_socket(sockfd);    
  if (!pb_encode_delimited(&output, Sample_fields, &message))
  {            
   printf("Encoding failed: %s\n", PB_GET_ERROR(&output));
  }

Java TCP Server (Netty based ) snippet :

// main calls run method

public void run() {
        EventLoopGroup ServerGroup = new NioEventLoopGroup();
        try{     
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(ServerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .childHandler(new ServerInitializer());
            ChannelFuture future = bootstrap.bind(1234).sync();
            future.channel().closeFuture().sync();
        } catch(Exception ex) {
            System.out.println(ex);
        }
        finally{
            System.out.println("Logging Off");
            ServerGroup.shutdownGracefully();
        }
    }

public class ServerInitializer extends ChannelInitializer<SocketChannel> {
     @Override
     public void initChannel(SocketChannel ch) throws Exception {
        try {       
           ChannelPipeline p = ch.pipeline();
           
           //add decoders and encoders
           p.addLast(new ProtobufVarint32FrameDecoder());
           p.addLast(new ProtobufDecoder(SampleProtos.Sample.getDefaultInstance()));
           p.addLast(new ProtobufVarint32LengthFieldPrepender());
           p.addLast(new ProtobufEncoder());
           
           //handler for business logic
           p.addLast(new ServerHandler());
        } catch (Exception ex) {
           System.out.println(ex);
        }
     }
}


public class ServerHandler extends ChannelInboundHandlerAdapter {
.........
@Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
      System.out.println("Channel Read...");
      
      try {
          SampleProtos.Sample sample = (SampleProtos.Sample)msg;
          System.out.println("Value Read: " + sample.getValue());
          sample = sample.toBuilder().setValue("Server Response").build();
          ctx.writeAndFlush(sample);
     } catch (Exception ex){
         System.out.println(ex);
     }
  }
  
}  
  

The server output is blank for C client but shows client sent data for Java Netty client. Any suggestion why my code is failing? Thanks in anticipation.

Dhiman
  • 59
  • 6
  • Solved it. Found that options with max_size were set at client side but the java server side was not having options. When I removed options at the client side and used encode_string instead of strcpy it worked ! Does it mean a char array and a string are encoded differently in nanopb ? – Dhiman Sep 01 '20 at 06:12
  • In cases like this, it is important to know the actual binary data being transmitted. You can see it using e.g. wireshark or other TCP analysis tool. – jpa Sep 01 '20 at 07:40
  • thanks,will try wireshark and pcap.. observed that Java server to C client response is correct even if no option is used at java side but used in C side.. using same code like network_server in client – Dhiman Sep 01 '20 at 16:45

0 Answers0