Netty依赖
<!-- https://mvnrepository.com/artifact/io.netty/netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.3.0.Final</version>
</dependency>
服务端ServerBootstrap
package com.nettyDemo;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.WriteCompletionEvent;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* 类中方法根据自己需求进行操作,客户端的基本一样
*/
class ServerHandler extends SimpleChannelHandler{
@Override
public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// TODO Auto-generated method stub
super.handleUpstream(ctx, e);
}
/**
* 接收消息
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
super.messageReceived(ctx, e);
System.out.println("服务器接收到客户消息:"+e.getMessage());
// 这里接受到客户端信息后,返回给客户端信息
ctx.getChannel().write("傻了吧,");
}
/**
* 捕获异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
super.exceptionCaught(ctx, e);
System.out.println("exceptionCaught");
}
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelOpen(ctx, e);
}
/**
* 通道打开时,并绑定到本地地址时调用,但是没有开启连接
*/
@Override
public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelBound(ctx, e);
}
/**
* 通道打开时,绑定到本地地址,连接远程地址
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelConnected(ctx, e);
}
@Override
public void channelInterestChanged(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelInterestChanged(ctx, e);
}
/**
* 你必须是连接已经建立,关闭通道时才会触发
*/
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelDisconnected(ctx, e);
System.out.println("channelDisconnected");
}
@Override
public void channelUnbound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelUnbound(ctx, e);
}
/**
* 通道关闭时触发
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelClosed");
}
@Override
public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
// TODO Auto-generated method stub
super.writeComplete(ctx, e);
}
@Override
public void childChannelOpen(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.childChannelOpen(ctx, e);
}
@Override
public void childChannelClosed(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.childChannelClosed(ctx, e);
}
@Override
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// TODO Auto-generated method stub
super.handleDownstream(ctx, e);
}
@Override
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
// TODO Auto-generated method stub
super.writeRequested(ctx, e);
}
@Override
public void bindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.bindRequested(ctx, e);
}
@Override
public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.connectRequested(ctx, e);
}
@Override
public void setInterestOpsRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.setInterestOpsRequested(ctx, e);
}
@Override
public void disconnectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.disconnectRequested(ctx, e);
}
@Override
public void unbindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.unbindRequested(ctx, e);
}
@Override
public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.closeRequested(ctx, e);
}
}
/**
*
* @author DongWei
* 2018年11月28日
*/
public class NettyServer {
public static void main(String[] args) {
// 创建服务类对象
ServerBootstrap serverBootstrap = new ServerBootstrap();
// 创建两个线程池,分别坚挺端口,nio监听
ExecutorService boos = Executors.newCachedThreadPool();
ExecutorService worker = Executors.newCachedThreadPool();
// 设置工程把两个线程池加入其中
serverBootstrap.setFactory(new NioServerSocketChannelFactory(boos, worker));
// 设置管道工厂 参数为创建管道,
serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeLine = org.jboss.netty.channel.Channels.pipeline();
// 将数据转换为String类型
// 这其中有转化为char类型方法
pipeLine.addLast("decoder",new StringDecoder());
pipeLine.addLast("encoder", new StringEncoder());
// 增加通道处理实体类,这里可以根据需要进行演示
pipeLine.addLast("serverHandler", new ServerHandler());
return pipeLine;
}
});
// 绑定端口号
serverBootstrap.bind(new InetSocketAddress(8080));
System.out.println("netty server --已启动...");
// 这里进行演示Ntty为非阻塞IO操作,浏览器通过地址
// http://127.0.0.1:8080访问服务器端演示Netty为非阻塞IO
// while(true){
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("这里每隔5秒打印一次");
// }
}
}
客户端ClientServer
/**
*
*/
package com.nettyDemo;
import java.net.InetSocketAddress;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.WriteCompletionEvent;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* 类中方法根据自己需求进行操作
*/
class ClientHandler extends SimpleChannelHandler{
@Override
public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// TODO Auto-generated method stub
super.handleUpstream(ctx, e);
}
/**
* 接收消息
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
super.messageReceived(ctx, e);
System.out.println("收到服务器回复信息:----"+e.getMessage());
}
/**
* 捕获异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
super.exceptionCaught(ctx, e);
System.out.println("exceptionCaught");
}
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelOpen(ctx, e);
}
/**
* 通道打开时,并绑定到本地地址时调用,但是没有开启连接
*/
@Override
public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelBound(ctx, e);
}
/**
* 通道打开时,绑定到本地地址,连接远程地址
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelConnected(ctx, e);
}
@Override
public void channelInterestChanged(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelInterestChanged(ctx, e);
}
/**
* 你必须是连接已经建立,关闭通道时才会触发
*/
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
super.channelDisconnected(ctx, e);
System.out.println("channelDisconnected");
}
@Override
public void channelUnbound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.channelUnbound(ctx, e);
}
/**
* 通道关闭时触发
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelClosed");
}
@Override
public void writeComplete(ChannelHandlerContext ctx, WriteCompletionEvent e) throws Exception {
// TODO Auto-generated method stub
super.writeComplete(ctx, e);
}
@Override
public void childChannelOpen(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.childChannelOpen(ctx, e);
}
@Override
public void childChannelClosed(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.childChannelClosed(ctx, e);
}
@Override
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// TODO Auto-generated method stub
super.handleDownstream(ctx, e);
}
@Override
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
// TODO Auto-generated method stub
super.writeRequested(ctx, e);
}
@Override
public void bindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.bindRequested(ctx, e);
}
@Override
public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.connectRequested(ctx, e);
}
@Override
public void setInterestOpsRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.setInterestOpsRequested(ctx, e);
}
@Override
public void disconnectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.disconnectRequested(ctx, e);
}
@Override
public void unbindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.unbindRequested(ctx, e);
}
@Override
public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
// TODO Auto-generated method stub
super.closeRequested(ctx, e);
}
}
/**
*
* @author DongWei
* 2018年11月28日
*/
public class NettyClinet {
public static void main(String[] args) {
System.out.println("netty clinet端启动");
// 创建客户端类
ClientBootstrap clientBootstrap = new ClientBootstrap();
// 创建客户端线程池
ExecutorService boos = Executors.newCachedThreadPool();
ExecutorService worker = Executors.newCachedThreadPool();
// 线程池放入客户端类
clientBootstrap.setFactory(new NioClientSocketChannelFactory(boos, worker));
// 设置客户端管道,创建连接工厂
clientBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
// 创建新的管道
ChannelPipeline pipeLine = Channels.pipeline();
pipeLine.addLast("decoder",new StringDecoder());
pipeLine.addLast("encoder",new StringEncoder());
pipeLine.addLast("clientHandler", new ClientHandler());
return pipeLine;
}
});
// 连接服务器端
ChannelFuture connet = clientBootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
// 获取通道
Channel channel = connet.getChannel();
// 将数据写入通道
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("请输入内容...");
channel.write(scanner.next());
}
}
}