2017-08-03 1 views
1

Ich habe zwei Server "A" (von meinen Freunden gebaut) und "B" (von mir gebaut, mit Netty 4.1). Dieser Server "A" und "B" würde eine Antwort zurückgeben, wenn der Client einen Befehl sendet. Ich habe versucht, diesen Server mit einfachen JAVA Client Socket. unten ist die Java-Client-Code:Netty: Server Socket offen lassen Nach ctx.flush()

public class SocketClient 
{ 
    public void run() 
    { 
     try { 
      ClassLoader classLoader = getClass().getClassLoader(); 
      File file = new File(classLoader.getResource("request.txt").getFile()); 
      String content = new String(Files.readAllBytes(file.toPath())); 

      System.out.println("Connecting to server:8888"); 
      Socket socket = new Socket("myserver.com", 8888); 
      DataOutputStream out = new DataOutputStream(socket.getOutputStream()); 
      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

      out.write(content.getBytes()); 
      out.flush(); 

      while(true) { 
       int response = in.read(); 
       System.out.println(response); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Wenn der Client zum Server A (Nicht-netty) verbinden, die read() Methode geben Sie mir die Ausgabe wie folgt aus:

48 
48 
57 
56 
48 
50 
49 
48 

aber, wenn ich versuche, eine Verbindung zum Server "B" (die netty verwendet), ist die Ausgabe wie folgt aus:

48 
48 
57 
56 
48 
50 
49 
48 
-1 
-1 
-1 
-1 

warum ist das passiert? durch die Art und Weise in Server B verwende ich ctx.write() and ctx.flush() und wie Server B zu machen, das gleiche Verhalten mit Server A erhalten (nicht die Verbindung geschlossen wird, so wird es nicht zurück -1)

bearbeiten: Zusätzliche Informationen

Eigentlich in Server "B" verwende ich ChannelInboundHandlerAdapter und ChannelOutboundHandlerAdapter. Nach einigen Experimenten ist das Problem auf ChannelOutboundHandlerAdapter. Wenn ich eine Antwort mit ctx.writeAndFlush() von InboundAdapter sende, ist der Socket nicht geschlossen. Aber wenn die Antwort in OutboundAdapter übergeben wird, dann sende ich die Antwort mit ctx.writeAndFlush() innerhalb OutboundAdapterwrite(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) Methode. Der Sockel ist geschlossen

hier ist die Probe meiner OutboundAdapter:

public class OutboundHandler extends ChannelOutboundHandlerAdapter { 

    private static final Logger logger = LogManager.getLogger(OutboundHandler.class); 

    //Sending or forwarding message to channel which is already configured 
    //condition is depends on which model instance 
    //packaging is worked on its packager class 
    @Override 
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception 
    { 
     String response = "Response form OutboundHandler"; 
     ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes())); 
    } } 

dank

Antwort

0

Nach dem Debugging den ganzen Tag, fand ich die Ursache des Problems. Ich habe aus Versehen ctx.close() irgendwo in meinem InboundAdapter, so, wenn ich die Nachricht in OutboundAdapter und bündig die Nachricht an den Client übergeben wird die Verbindung

try { 
    //some code 
} 
} catch (Exception ex) { 
     logger.error(ex); 
     ErrorData error = new ErrorData(); 
     error.setCode("99"); 
     error.setMessage("General System Error"); 

     //pass the message to OutboundAdapter 
     ctx.writeAndFlush(error); 
} finally { 
    ctx.close(); 
} 

so nah, ich brauche nur die ctx.close() und der Server entfernen gestoppt aus Schließen der Socket-Verbindung

0

Auf Netty Server Implementierung, vielleicht müssen Sie behandeln über ChannelHandlerContext mehr richtig zum Beispiel Lesen/Schreiben, statt mit ctx.write()ctx.channel().writeandflush() soll richtiger Weg sein, auch beim Schließen Nutzung von ctx.channel().close() oder ctx.channel().close().sync() könnten Unterschiede machen ...

+0

Was ist der Unterschied zwischen 'ctx.writeAndFlush()' und 'ctx.channel.writeAndFlush()'? Mein Problem ist Netty immer schließen Sie die Verbindung automatisch nach 'writeAndFlush()', so dass der Client keine andere Nachricht an den Server senden kann. –

+0

Sie sollten in beiden Weisen gleich sein, sie implementieren die gleiche ChannelOutboundInvoker Schnittstelle obwohl, für Ihr Problem, das ich einige netty Beispiel, das nützlich sein könnte https://developer.jboss.org/wiki/NettyExampleOfPingPongUsingObject –

+0

durch die Art und Weise, die ich nety benutze. io (ver 4.x) und nicht jboss netty (ver 3.x), ich weiß nicht, ob sie einen signifikanten Unterschied haben. aber danke für den Vorschlag ... oh, und ich habe versucht, 'ctx.write(); ctx.flush() 'in' ctx.channel(). writeAndFlush() 'aber der Socket wird immer noch automatisch geschlossen. –

0

Sie suchen nicht nach dem Ende des Streams, also wiederholen Sie es endlos. read() gibt einen Wert zurück. Prüfen Sie. Am Ende des Streams wird -1 zurückgegeben. Das ist das Ende. Finis. Finito. Halte dort an. Drucken Sie es nicht. Lies nicht weiter. Überhole GO nicht. Sammle keine $ 200 ein.

Verwandte Themen