package com.server;
import org.jboss.netty.channel.Channels;
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.socket.nio.NioServerSocketChannelFactory;
public class Server {
public static void main(String[] args) {
//1.创建一个Netty服务类
/**
* ServerBootstrap 是一个启动NIO服务的辅助启动类
* 你可以在这个服务中直接使用Channel
* */
ServerBootstrap bootstrap = new ServerBootstrap();
//2.创建两个线程池
/**
* 第一个经常被叫做‘boss’,用来接收进来的连接。
* 第二个经常被叫做‘worker’,用来处理已经被接收的连接,
* 一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。
* */
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService worker = Executors.newCachedThreadPool();
//3.为服务类设置一个NioSocket工厂
bootstrap.setFactory(new NioServerSocketChannelFactory(boss, worker));
//4.设置管道的工厂(匿名内部类实现)
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
//设置一个处理服务端消息和各种消息事件的类(Handler)
pipeline.addLast("hellohandler", new HelloHandler());
return pipeline;
}
});
//5.为服务端设置一个端口
bootstrap.bind(new InetSocketAddress(10101));
System.out.println("server start!");
}
}
其中的HelloHandler也是我们自己新建的,继承了SimpleChannelHandler:
package com.server;
import org.jboss.netty.buffer.ChannelBuffer;
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;
public class HelloHandler extends SimpleChannelHandler{
/**
* 连接关闭
* */
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
System.out.println("channelClosed");
super.channelClosed(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);
}
/**
* 捕获异常
* */
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
System.out.println("exceptionCaught,error:"+e.toString());
super.exceptionCaught(ctx, e);
}
/**
* 消息接收
* */
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
System.out.println("messageReceived");
//获取到的信息是使用ChannelBuffer包装的字节流
ChannelBuffer message = (ChannelBuffer)e.getMessage();
String msg = new String(message.array());//将字节流转换为String
System.out.println(msg);//打印收到的字符串
super.messageReceived(ctx, e);
}
}
实现了以下方法:
//4.设置管道的工厂(匿名内部类实现)
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
//设置解码方式为String
pipeline.addLast("decoder", new StringDecoder());
//设置一个处理服务端消息和各种消息事件的类(Handler)
pipeline.addLast("hellohandler", new HelloHandler());
return pipeline;
}
});
然后接收方法我们直接使用String接收即可:
/**
* 消息接收
* */
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
System.out.println("messageReceived");
String msg = (String)e.getMessage();//将字节流转换为String
System.out.println(msg);//打印收到的字符串
super.messageReceived(ctx, e);
}
实验:
/**
* 消息接收
* */
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
System.out.println("messageReceived");
String msg = (String)e.getMessage();//将字节流转换为String
System.out.println(msg);//打印收到的字符串
//回写数据(需要用ChannelBuffer包装要回复的字节流信息)
ChannelBuffer channelBuffer = ChannelBuffers.copiedBuffer("hi".getBytes());
ctx.getChannel().write(channelBuffer);
super.messageReceived(ctx, e);
}
即是使用ChannelHandlerContext获取Channel,然后使用writer我们需要给客户端回复的信息。
以上就是一个基于Netty技术的的网络通信服务端的一个样例,下一篇讲解基于Netty的客户端的样例,并且与本篇的服务端进行通信。
转载请注明出处:https://blog.csdn.net/acmman/article/details/80298062