netty的DISCARD服務報錯,我是這個樣子解決的
阿新 • • 發佈:2018-12-10
我在學習netty時,練習的是DISCARD服務,在netty裡面,丟棄服務就是Server端不去對Client端傳送資料進行處理,直接進行釋放,為了展示效果,我添加了部分反饋程式碼,以下是我的程式碼,
Client端
package com.nettyTest.NettyDemo; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; public class Client { public static void main(String[] args) throws Exception { //建立工程執行緒組 EventLoopGroup workerGroup = new NioEventLoopGroup(); //建立輔助陣列,ServerBootstrap負責初始化netty伺服器,並且開始監聽埠的socket請求。 Bootstrap b = new Bootstrap(); // (1) //將工程執行緒組加入到公作組裡面 b.group(workerGroup); // (2) //指定處理通訊管道型別 b.channel(NioSocketChannel.class); // (3) //把ClientHandler新增到ServerBootstrap處理伺服器端發過來的資訊 b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel sc) throws Exception { sc.pipeline().addLast( new ClientHandler()); } }); // 啟動客戶端並載入連線埠127.0.0.1:8080 ChannelFuture cf1 = b.connect("127.0.0.1", 8080).sync(); // (5) //從管道里面寫入資料Unpooled.copiedBuffer將位元組陣列 bytep[]轉成緩衝流 Buffer cf1.channel().write(Unpooled.copiedBuffer("777".getBytes())); // flush()把緩衝區的內容強制的寫出 cf1.channel().flush(); // 等待連線關閉. cf1.channel().closeFuture().sync(); //關閉工作執行緒 workerGroup.shutdownGracefully(); } }
ClietHandler處理Server發過來的資訊
package com.nettyTest.NettyDemo; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; public class ClientHandler extends ChannelHandlerAdapter { //重寫channelRead方法, @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // TODO Auto-generated method stub //建立緩衝區buf ByteBuf buf = (ByteBuf) msg; //建立位元組陣列data byte[] data=new byte[buf.readableBytes()]; //將緩衝區buf的內容寫入data buf.readBytes(data); //將位元組陣列data轉為字串request,指定字符集 String request = new String(data, "utf-8"); System.out.println("Client: "+request); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // TODO Auto-generated method stub cause.printStackTrace(); ctx.close(); } }
Server端
package com.nettyTest.NettyDemo; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class Server { public static void main(String[] args) throws Exception{ //建立接收執行緒組,接收Client端發過來的資訊 EventLoopGroup bossGroup=new NioEventLoopGroup(); //建立工作執行緒組,處理實際業務 EventLoopGroup workerGroup=new NioEventLoopGroup(); //建立輔助類負責初始化netty伺服器,並且開始監聽埠的socket請求 ServerBootstrap b=new ServerBootstrap(); //把兩個執行緒組加入到輔助類Bootstrap裡面去 b.group(bossGroup,workerGroup) //指定處理通訊管道型別 .channel(NioServerSocketChannel.class) //把ServerHandler新增到ServerBootstrap處理伺服器端發過來的資訊 .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { sc.pipeline().addLast(new ServerHandler()); } }); //伺服器開始監聽埠8080 ChannelFuture f=b.bind(8080).sync(); //等待連線關閉 f.channel().closeFuture().sync(); //關閉接收執行緒組 bossGroup.shutdownGracefully(); //關閉工作執行緒組 workerGroup.shutdownGracefully(); } }
ServHandler處理 Client端發過來的資訊,同時也可以傳送資訊給Client端
package com.nettyTest.NettyDemo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class ServerHandler extends ChannelHandlerAdapter {
//重寫channelRead方法,
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// TODO Auto-generated method stub
//建立緩衝區buf
ByteBuf buf = (ByteBuf) msg;
//建立位元組陣列data
byte[] data=new byte[buf.readableBytes()];
//將緩衝區buf的內容寫入data
buf.readBytes(data);
//將位元組陣列data轉為字串request,指定字符集
String request = new String(data, "utf-8");
System.out.println("Server: "+request);
//伺服器給客戶端的響應
String response ="我是反饋的資訊";
//從管道里面寫入資料Unpooled.copiedBuffer將位元組陣列 bytep[]轉成緩衝流 Buffer
ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// TODO Auto-generated method stub
cause.printStackTrace();
ctx.close();
}
}
一開始的時候我直接啟動Client端程式碼,然後是DISCARD服務報錯,報錯程式碼在下面,
Exception in thread "main" java.net.ConnectException: Connection refused: no further information: /127.0.0.1:8080
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:223)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:276)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:531)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:471)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:385)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:351)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)
at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)
at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)
at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)
at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)
at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)
然後我去百度一下,網上提供了三個方法進行排查 ,
1,防火牆進行攔截,導致Client連線被攔截,然後我去關閉了防火牆,發現仍然報錯
2,埠被佔用,我去使用netstat -ano | findstr "8080" 檢視,沒有發現埠被佔用
3.要看你的server是否真正的執行起來了,比如server在啟動過程某些元件載入異常,會導致服務啟動不成功,我重啟了server端,然後啟動了Client端,然後錯誤解決了。