1. 程式人生 > >netty報錯:遠端主機強迫關閉了一個現有的連線。(已解決)

netty報錯:遠端主機強迫關閉了一個現有的連線。(已解決)

昨天,java 整合netty服務的專案,在測試伺服器上,發現了一個問題:

1.專案netty包版本:netty-all-5.0.0.Alpha1.jar。

2.問題的描述:伺服器啟動,各種通訊正常,執行一段時間,大概10分鐘後,這個問題就出現了,並且客戶端傳送上來的資料,不再收到回寫資料,感覺就是被卡死了。

3.錯誤資訊如下:

java.io.IOException: 你的主機中的軟體中止了一個已建立的連線。
	at sun.nio.ch.SocketDispatcher.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
	at sun.nio.ch.IOUtil.read(IOUtil.java:192)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379)
	at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:446)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:871)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:208)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:119)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
	at java.lang.Thread.run(Thread.java:745)

(找了很多部落格,都沒能解決到問題,但是從各個博文中,我就感覺我程式碼依然是有問題的。)

 

直到今天,終於解決了!!!!

最後我是這樣解決的(我始終感覺我犯的是一個低階的錯誤,真的是恨自己。):

1.找到你讀取通道資料的方法:public void channelRead(ChannelHandlerContext ctx, Object msg)。

2.檢查這個方法中的程式碼,我這裡是由於沒有新增ctx.flush()導致出錯:

我這裡加上後,netty通訊正常。

 

Tips:下面這2個方法,也需要flush()或者close()

	/**
	 * channelReadComplete channel 通道 Read 讀取 Complete 完成
	 * 在通道讀取完成後會在這個方法裡通知,對應可以做重新整理操作 ctx.flush()
	 */
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	/**
	 * exceptionCaught exception 異常 Caught 抓住
	 * 抓住異常,當發生異常的時候,可以做一些相應的處理,比如列印日誌、關閉連結
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		//super.exceptionCaught(ctx, cause);
		ctx.close();
		log.error("異常資訊:", cause);
		System.out.println("異常資訊:\r\n" + cause.getMessage());
		
	}