1. 程式人生 > >netty的DISCARD服務報錯,我是這個樣子解決的

netty的DISCARD服務報錯,我是這個樣子解決的

我在學習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端,然後錯誤解決了。