Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。本文则是基于udp通信讲解。
1.服务端
public class UdpServer {
private static final String TAG = UdpServer.class.getSimpleName();
private static UdpServer instance=new UdpServer();
private Bootstrap bootstrap;
private EventLoopGroup worker;
private RemoteContext mContext;
private UdpOperationDecoder od;
private UdpPacketEncoder pe;
public static UdpServer getInstance(){
return instance;
}
private UdpServer() {
od=new UdpOperationDecoder();
pe=new UdpPacketEncoder();
}
public void start(){
mContext=new RemoteContext();
worker=new NioEventLoopGroup();
bootstrap=new Bootstrap()
.group(worker)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.option(ChannelOption.SO_REUSEADDR, true)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
LogUtils.e("udp有客户端连接上来:");
ch.pipeline()
.addLast(pe)
.addLast(od)
.addLast(new OperationHandler(mContext));
}
}).localAddress(ConfigInfo.UDP_PORT);
bootstrap.bind();
}
public void stop(){
worker.shutdownGracefully();
worker=null;
mContext=null;
bootstrap=null;
}
}
@ChannelHandler.Sharable
public class UdpOperationDecoder extends MessageToMessageDecoder<DatagramPacket> {
private static final String TAG = UdpOperationDecoder.class.getSimpleName();
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
ByteBuf buf=msg.content();
short type=buf.readUnsignedByte();
Log.e("youdianxiaoshuai","decoded+type===="+type);
Operation op;
switch (type){
case Packet.REMOTE_CONTROL:
op = new RemoteControl(msg.sender()).init(buf);
break;
case Packet.CLIENT_TCP_CONNECT:
op = new ClientTcpConnect(msg.sender()).init(buf);
break;
default:
throw new RemoteException(RemoteException.UNKNOWN_TYPE, "未知命令");
}
if(buf.refCnt() >= 1){
buf.release();
}
out.add(op);
}
}
2.客户端
public class UdpClient {
private static final String TAG = UdpClient.class.getSimpleName();
private static final String POST = "localhost";
private static UdpClient instance=new UdpClient();
private Bootstrap bootstrap;
private EventLoopGroup worker;
private RemoteContext mContext;
private UdpOperationDecoder od;
private UdpPacketEncoder pe;
private Channel channel;
// private ExecutorService executorService = Executors.newFixedThreadPool(5);
public static UdpClient getInstance(){
return instance;
}
private UdpClient() {
od=new UdpOperationDecoder();
pe=new UdpPacketEncoder();
}
public void start(){
mContext=new RemoteContext();
worker=new NioEventLoopGroup();
bootstrap=new Bootstrap()
.group(worker)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
Log.e("joryuan","UDP连接成功"+ch.remoteAddress() + "==ch.local==="+ch.localAddress());
ch.pipeline()
.addLast(pe)
.addLast(od)
.addLast(new OperationHandler(mContext));
}
});
channel = bootstrap.bind(ConfigInfo.PHONE_UDP_PORT).syncUninterruptibly().channel();
}
public void sendRequest(int request, final int remoteControlCode){
switch (request){
case Packet.REMOTE_CONTROL:
RemoteControl.getInstance().setRemoteControlCode(remoteControlCode).sendRequest(channel);
break;
case Packet.CLIENT_TCP_CONNECT:
ClientTcpConnect.getInstance().sendRequest(channel);
break;
default:
}
}
public void stop(){
if(channel != null){
channel.disconnect();
channel.close();
channel = null;
}
if(worker != null){
worker.shutdownGracefully();
worker=null;
}
mContext=null;
bootstrap=null;
}
}
@ChannelHandler.Sharable
public class UdpOperationDecoder extends MessageToMessageDecoder<DatagramPacket> {
private static final String TAG = "UdpOperationDecoder";
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws RemoteException {
ByteBuf buf=msg.content();
short type=buf.readUnsignedByte();
Log.e("joryuan","type====="+type);
Operation op;
switch (type){
case Packet.REMOTE_CONTROL:
// op = new RemoteControl().init(buf);
op = RemoteControl.getInstance().init(buf);
break;
case Packet.CLIENT_TCP_CONNECT:
op = ClientTcpConnect.getInstance().setInetSocketAddress(msg.sender()).init(buf);
// op = new ClientTcpConnect(msg.sender()).init(buf);
break;
default:
throw new RemoteException(RemoteException.UNKNOWN_TYPE, "未知命令");
}
out.add(op);
}
}