2016-11-29 1 views
0

Wenn Sie versuchen, mit netty zu schreiben, enden die geschriebenen Daten nie auf der entfernten Seite, bestätigt mit Wireshark.Netty schreibt nicht

Ich habe versucht:

//Directly using writeAndFlush 
channel.writeAndFlush(new Packet()); 

//Manually flushing 
channel.write(new Packet()); 
channel.flush(); 

// Even sending bytes won't work: 
channel.writeAndFlush(new byte[]{1,2,3}); 

Keine Ausnahme Haken ist, wenn ich es in try{...}catch(Throwable e){e.printStackTrace();}

wickeln Was kann ich dieses Problem zu debuggen tun?

Antwort

4

Netty ist ein asynchrones Programm, dh es werden keine Ausnahmen ausgelöst, wenn ein Schreibvorgang fehlgeschlagen ist. Anstatt Ausnahmen auszugeben, gibt es eine Future<?> zurück, die aktualisiert wird, wenn die Anfrage abgeschlossen ist. Achten Sie darauf, alle Ausnahmen protokollieren von diesem als erste Debuggen Schritte kommen:

channel.writeAndFlush(...).addListener(new GenericFutureListener<Future<Object>>() { 
    @Override 
    public void operationComplete(Future<Object> future) { 
     // TODO: Use proper logger in production here 
     if (future.isSuccess()) { 
      System.out.println("Data written succesfully"); 
     } else { 
      System.out.println("Data failed to write:"); 
      future.cause().printStackTrace(); 
     } 
    } 
}); 

Oder einfacher:

channel.writeAndFlush(...).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); 

Nachdem Sie die Ursache für die Ausnahme erhalten, könnte es mehrere Probleme:

java.lang.UnsupportedOperationException:
unsupported message type: <type> (expected: ...)

Hinweis: Diese wirft auch wenn ein ObjectEncoder verwenden, aber das Objekt nicht implementiert eine Standard Netty nicht Serializable

Kanal kann ByteBuf s und FileRegion s nur senden. Sie müssen Ihre Objekte in diese Typen konvertieren, indem Sie entweder weitere Handler zur Pipeline hinzufügen oder sie manuell in ByteBuf s konvertieren.

Ein ByteBuf ist die Netty-Variante eines Byte-Arrays, aber hat das Potenzial für die Leistung, da es im direkten Speicherbereich gespeichert werden kann.

Die folgenden Handler werden häufig verwendet:

ein String ein StringEncoder verwenden zu konvertieren ein Serializable eine ObjectEncoder (Warnung, nicht kompatibel mit normalen Java-Objekt-Streams) verwenden konvertieren Um eine byte[] Verwendung a zu umwandeln ByteArrayEncoder

Hinweis: Da TCP ein Stream-basiertes Protokoll ist, Sie usuall Sie möchten irgendeine Form von Paketgrößen haben, da Sie möglicherweise keine exakten Pakete erhalten, die Sie schreiben. Weitere Informationen finden Sie unter Dealing with a Stream-based Transport im Netty-Wiki.