2017-07-03 1 views
1

serveur a obtenu une erreur: Le numéro de message du protocole était invalide. Est-ce que mon code C# a besoin de sérialiser l'objet Personne?C# client connect serveur java netty utilisant protobuf

maven configurer

<dependencies> 
    <dependency> 
     <groupId>io.netty</groupId> 
     <artifactId>netty-all</artifactId> 
     <version>4.1.12.Final</version> 
    </dependency> 

    <dependency> 
     <groupId>com.google.protobuf</groupId> 
     <artifactId>protobuf-java</artifactId> 
     <version>3.3.1</version> 
    </dependency> 

    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

code serveur

public class AppServer { 
    public void startSocket(int port) throws Exception { 
    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 

    try { 
     ServerBootstrap serverBootstrap = new ServerBootstrap(); 
     serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 
       .option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO)) 
       .childHandler(new ChannelInitializer<SocketChannel>() { 

        @Override 
        protected void initChannel(SocketChannel ch) throws Exception { 
         ch.pipeline().addLast(new ProtobufVarint32FrameDecoder()); 
         ch.pipeline().addLast(new ProtobufDecoder(Person.getDefaultInstance())); 
         ch.pipeline().addLast(new ProtobufServerHandler()); 

        } 
       }); 
     ChannelFuture future = serverBootstrap.bind(port).sync(); 
     System.out.println("Server Starting."); 
     future.channel().closeFuture().sync(); 
    } finally { 
     bossGroup.shutdownGracefully(); 
     workerGroup.shutdownGracefully(); 
    } 
} 

public static class ProtobufServerHandler extends ChannelInboundHandlerAdapter { 
    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 
     Person person = (Person) msg; 
     System.out.println(person); 
    } 

    @Override 
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
     // TODO Auto-generated method stub 
     super.channelReadComplete(ctx); 
    } 

    @Override 
    public void channelActive(ChannelHandlerContext ctx) throws Exception { 
     super.channelActive(ctx); 
     Person john = Person.newBuilder().setId(1234).setName("John Doe").setEmail("[email protected]") 
       .addPhones(Person.PhoneNumber.newBuilder().setNumber("555-4321").setType(Person.PhoneType.HOME)) 
       .build(); 
     ctx.writeAndFlush(john); 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
     cause.printStackTrace(); 
    } 
} 

public static void main(String[] args) throws Exception { 
    int port = 8081; 

    if(args != null && args.length > 0){ 
     port = Integer.valueOf(args[0]); 
    } 

    new AppServer().startSocket(port); 
    } 
} 

C# code client

namespace proto 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     socket.Connect("127.0.0.1", 8081); 
     Console.WriteLine("===========connect to server==========="); 

     var buffer = new byte[1024 * 1024]; 
     socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); 

     SendMessage(socket); 

     if (socket.Connected) 
     { 
      socket.Shutdown(SocketShutdown.Both); 
     } 


     Console.Read(); 
    } 

      private static void SendMessage(Socket socket) 
    { 
     var sam = new Person(); 
     sam.Name = "John Doe"; 
     sam.Email = "[email protected]"; 
     sam.Id = 1234; 
     sam.Phones.Add(new Person.Types.PhoneNumber() 
     { 
      Number = "555-4321", 
      Type = Person.Types.PhoneType.Home 
     }); 

     if (socket.Connected) 
     { 
      var stream = new MemoryStream(); 
      var aa = sam.ToByteArray(); 

      socket.BeginSend(aa, 0, aa.Length, SocketFlags.None, null, null);     
     } 
    } 

    private static void ReceiveMessage(IAsyncResult ar) 
    { 
     Console.WriteLine("===========receive from server==========="); 
     Console.WriteLine(ar); 
    } 
} 
    } 

.proto fichier

// See README.txt for information and build instructions. 
    // 
    // Note: START and END tags are used in comments to define sections used in 
    // tutorials. They are not part of the syntax for Protocol Buffers. 
    // 
    // To get an in-depth walkthrough of this file and the related examples, see: 
    // https://developers.google.com/protocol-buffers/docs/tutorials 

    // [START declaration] 
    syntax = "proto3"; 
    package tutorial; 
    // [END declaration] 

    // [START java_declaration] 
    option java_package = "com.example.tutorial"; 
    option java_outer_classname = "AddressBookProtos"; 
    // [END java_declaration] 

    // [START csharp_declaration] 
    option csharp_namespace = "Google.Protobuf.Examples.AddressBook"; 
    // [END csharp_declaration] 

    // [START messages] 
    message Person { 
    string name = 1; 
    int32 id = 2; // Unique ID number for this person. 
    string email = 3; 

    enum PhoneType { 
     MOBILE = 0; 
     HOME = 1; 
     WORK = 2; 
    } 

    message PhoneNumber { 
     string number = 1; 
     PhoneType type = 2; 
    } 

    repeated PhoneNumber phones = 4; 
    } 

    // Our address book file is just one of these. 
    message AddressBook { 
    repeated Person people = 1; 
    } 
    // [END messages] 

erver a obtenu une erreur: L'étiquette de message de protocole avait un type de fil invalide. Y at-il mon code de C# besoin de sérialiser l'objet Personne?

Répondre

0

Votre code serveur fait référence à un décodeur de trame basé sur varint (ProtobufVarint32FrameDecoder) - anticipant vraisemblablement un message (trame) à préfixe de longueur. Cependant, votre code client envoie un protobuf brut sans aucun mécanisme de cadrage.

Je suggère que vous ayez besoin d'ajouter le framing au code client, via n'importe quelle API qu'il expose pour tel (si c'était protobuf-net, ce serait la méthode SerializeWithLengthPrefix).