2014-09-26 32 views
-1

我正在處理一個簡單的應用程序。 我想了解我的例外,但我不能。無法連接到Netty服務器兩次

如何重現:

  1. 開始的Netty服務器
  2. 連接到服務器的Netty與客戶端 - >有效的響應,服務器+客戶端工作正常。
  3. 客戶端關閉(0激活通道,通過調試線程證明)
  4. 新的客戶端試圖讀取 - >錯誤:java.net.SocketException異常:軟件導致連接中止:recv的失敗
  5. 重新啓動服務器,轉到2 。

Server源:

public class Server { 

private final int port; 

public Server(int port) { 
    this.port = port; 
} 

public void run() throws Exception { 
    final EventLoopGroup boss = new NioEventLoopGroup(); 
    final EventLoopGroup worker = new NioEventLoopGroup(); 
    try { 
     final ServerBootstrap b = new ServerBootstrap(); 
     b.group(boss, worker) 
       .channel(NioServerSocketChannel.class) 
       .childHandler(new SocketChannelInitializer()); 

     final ChannelFuture f = b.bind(port).sync(); 
     final ChannelFuture c = f.channel().closeFuture(); 
     System.out.println("- DONE -"); 

     c.sync(); 
    } finally { 
     worker.shutdownGracefully(); 
     boss.shutdownGracefully(); 
    } 
} 

public static void main(String[] args) throws Exception { 
    int port; 
    if (args.length > 0) { 
     port = Integer.parseInt(args[0]); 
    } else { 
     port = 8080; 
    } 
    new Server(port).run(); 
} 

}

我Initialisizer:

public static final String PACKET = "packet"; 
public static final String STRING_DECODER = "stringDecoder"; 
public static final String NETWORK_HANDLER = "networkHandler"; 

@Override 
public void initChannel(SocketChannel ch) throws Exception { 
    System.out.println("Creating new Channel!"); 
    final ChannelPipeline p = ch.pipeline(); 
    p.addLast(NETWORK_HANDLER, new NetworkHandler()); 
    p.addLast(STRING_DECODER, new StringDecoder(CharsetUtil.UTF_8)); 
    p.addLast(new Testdecoder()); 
    p.addLast(new ChatAdapter()); 
} 

服務器DOES處理請求,但它不能讀取正確的消息。

我的客戶:

public static void main(String[] args) throws IOException { 
    final Socket s = new Socket(); 
    s.connect(new InetSocketAddress("localhost", 8080)); 
    final InputStream is = s.getInputStream(); 
    final OutputStream os = s.getOutputStream(); 
    os.write(0x0); 
    os.write("username".getBytes(CharsetUtil.UTF_8)); 
    os.flush(); 
    System.out.println("!"); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

    byte[] b = new byte[4096]; 
    while (true) { 
     int n = is.read(b); 
     if (n < 0) { 
      break; 
     } 
     baos.write(b, 0, n); 
    } 

    byte data[] = baos.toByteArray(); 
    System.out.println(new String(data, CharsetUtil.UTF_8)); 
    System.out.println("- DONE -"); 
    s.close(); 
} 

使用的Netty 4.0.23.Final

示例應用: https://github.com/BjoernAkAManf/Chat

啓動Server.main(字串[] args),然後運行Client.main( String [] args)兩次。您將首先獲得正確的輸出。第二次運行將失敗。 我測試了我可能想到的任何東西。真的很感謝這裏的幫助。謝謝

+0

Downvoting沒有任何評論。這很不錯。我試圖自己調試整個程序,幾天工作相當辛苦 - 我不是故意冒犯任何人,但如果你冷靜地提出問題,至少告訴我原因 - 這個問題很容易重現,只需自己測試一下。如果問題與我的處理程序有某種關係,則會在某處拋出或打印異常。在我的邏輯中必然存在一個缺陷 - 以前沒有人報告過這個問題,我在這裏使用馬廄。 – manf 2014-10-22 19:36:06

回答

0

儘管我的第一個想法,這不是一個'真正'的服務器問題,也不是一個NETTY的問題。客戶端使用oio(java.IO)套接字連接到Nio Netty服務器。

將NioEventLoopGroup更改爲OioEventLoopGroup,將NioServerSocketChannel更改爲OioServerSocketChannel可以解決這個奇怪的問題。

此外,人們可能會更改客戶端與Nio一起工作。在下面的示例中,我將使用java.nio:

final SocketChannel c = SocketChannel.open(); 
    c.connect(new InetSocketAddress("localhost", 8007)); 

    final ByteBuffer buf = ByteBuffer.allocate(5); 

    // fill Buffer 
    buf.put((byte) 0x0); 
    buf.put("Test".getBytes(CharsetUtil.UTF_8)); 
    // Flip buffer 
    buf.flip(); 

    // Write buffer to socket 
    while (buf.hasRemaining()) { 
     c.write(buf); 
    } 

    System.out.println("Reading ..."); 

    // Read 
    buf.flip(); 
    while (true) { 
     int n = c.read(buf); 
     if (n < 0) { 
      break; 
     } 
     final String d = new String(buf.array()); 
     if(!d.isEmpty()) System.out.println("'" + d + "'"); 
     buf.clear(); 
    } 

    // Finish Programm 
    System.out.println("- DONE -"); 
    c.close(); 

該示例工作得很好。很明顯,這個問題在我眼前是正確的。

現在已修復。