Netty之HelloWorld
本例子用的是Netty3.0版本的jar,后面会用5.0版本的。
引用的jar包如上图所示。
1、接下来创建Server类
package com.server;
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.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;
/**
* netty服务端入门
*
* HelloWorld
*/
public class Server {
public static void main(String[] args) {
//服务类
ServerBootstrap bootstrap = new ServerBootstrap();
//boss线程监听端口,worker线程负责数据读写
//这里声明了两个线程池。netty5.0版本这里声明的是EventLoopGroup.本质 上还是一个线程池
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService worker = Executors.newCachedThreadPool();
//设置niosocket工厂
bootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker));
//设置管道的工厂
//管道的作用类似于过滤器
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
//对字符解密
pipeline.addLast("decoder", new StringDecoder());
//对字符加密
pipeline.addLast("encoder", new StringEncoder());
//绑定handler,hangdler用来处理从客户端接收的消息
pipeline.addLast("helloHandler", new HelloHandler());
return pipeline;
}
});
//绑定端口
bootstrap.bind(new InetSocketAddress(10101));
System.out.println("start!!!");
}
}
handler处理类:
package com.server;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
/**
* 消息接受处理类
* helloHandler继承SimpleChannelHandler
* 继承了下面的几个方法,还有很多,这里就先挑这几个。
*
*/
public class HelloHandler extends SimpleChannelHandler {
/**
* 接收消息
* 接受客户端的消息
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
String s = (String) e.getMessage();
System.out.println(s);
//回写数据
ctx.getChannel().write("hi");
super.messageReceived(ctx, e);
}
/**
* 捕获异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.out.println("exceptionCaught");
super.exceptionCaught(ctx, e);
}
/**
* 新连接
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelConnected");
super.channelConnected(ctx, e);
}
/**
* 必须是链接已经建立,关闭通道的时候才会触发
*/
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelDisconnected");
super.channelDisconnected(ctx, e);
}
/**
* channel关闭的时候触发
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelClosed");
super.channelClosed(ctx, e);
}
}
现在netty简单的服务端已经写好了。下面就可以启动了。我们用windows telnet窗口作为客户端,先跑一把看看效果。
telnet命令默认是不打开的,打开的话要去windows设置打开,具体可以百度。
启动start类。
进入cmd,输入telnet命令。
因为是本地启动的,所以输入 telnet 127.0.0.1 10101
回车,然后看控制台:
输出 channelConnected。是因为进入了helloHandler的下面这个方法
/**
* 新连接
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelConnected");
super.channelConnected(ctx, e);
}
然后咱们在客户端输出一个字母“S”.看客户端和服务端都出现什么。
我们看到服务端输出了客户端输入的“s”,而客户端显示“hi”。原因如下:
我们看下面这段代码:
/**
* 接收消息
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
String s = (String) e.getMessage();
System.out.println(s);
//回写数据
ctx.getChannel().write("hi");
super.messageReceived(ctx, e);
}
在服务端的handler类的messageReceived方法中 我们做了处理。1、服务端控制台输出接受的消息。2、然后回写“hi”给客户端。所以就出现了上面的展示。
好了,本次简单的netty 服务端就到这里。下次讲客户端。