Netty4入门(二)

/**
 * 
 */
package com.a;

/**
 *
 */
public class Constant {
	
	public final static int HEADER_FLAG = 123456789;
	
}
/**
 * 
 */
package com.a;

/**
 * 请求消息
 */
public class RequestMsg {
	
	private int module;
	private int cmd;
	private byte[] data;
	
	public int getModule() {
		return module;
	}
	public void setModule(int module) {
		this.module = module;
	}
	public int getCmd() {
		return cmd;
	}
	public void setCmd(int cmd) {
		this.cmd = cmd;
	}
	public byte[] getData() {
		return data;
	}
	public void setData(byte[] data) {
		this.data = data;
	}
	
}
/**
 * 
 */
package com.a;

/**
 * 返回消息
 */
public class ResponseMsg {
	
	private int module;
	private int cmd;
	private int code;
	private byte[] data;
	
	public int getModule() {
		return module;
	}
	public void setModule(int module) {
		this.module = module;
	}
	public int getCmd() {
		return cmd;
	}
	public void setCmd(int cmd) {
		this.cmd = cmd;
	}
	public int getCode() {
		return code;
	}
	public void setCode(int code) {
		this.code = code;
	}
	public byte[] getData() {
		return data;
	}
	public void setData(byte[] data) {
		this.data = data;
	}
	
}

服务程序

/**
 * 
 */
package com.a.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 {
		
		ServerBootstrap server = new ServerBootstrap();
		
		EventLoopGroup parentGroup = new NioEventLoopGroup();
		EventLoopGroup childGroup = new NioEventLoopGroup();
		server.group(parentGroup, childGroup);
		
		server.channel(NioServerSocketChannel.class);
		
		server.childHandler(new ChannelInitializer<SocketChannel>() {
			@Override
			public void initChannel(SocketChannel ch) throws Exception {
				//接受消息解码
				ch.pipeline().addLast(new RequestDecoder());
				//消息处理
				ch.pipeline().addLast(new ZukServerHandler());
				//返回消息编码
				ch.pipeline().addLast(new ZukServerResponseEncoder());
				
			}
		});
	
		server.option(ChannelOption.SO_BACKLOG, 2048);// 链接缓冲池队列大小
		server.bind(10102).sync();
		
	}

}
/**
 * 
 */
package com.a.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

import com.a.Constant;
import com.a.RequestMsg;

/**
 * 解码请求消息
 */
public class RequestDecoder extends ByteToMessageDecoder{
	
	/***
	 * +-----------------------------------------------------------
	 * | 包头(int)4 | 模块(int)4  | 命令(int)4  | 数据长度(int)4  | ......
	 * +-----------------------------------------------------------
	 */
	public static int BASE_LENTH = 4 + 4 + 4 + 4;

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {

		System.out.println("ZukServerRequestDecoder.decode.解码请求消息");
		
		while(true){
			if(buffer.readableBytes() >= BASE_LENTH){
				//第一个可读数据包的起始位置
				int beginIndex = 0;
				
				while(true) {
					//包头开始游标点
					beginIndex = buffer.readerIndex();
					
					//标记初始读游标位置
					buffer.markReaderIndex();
					if (buffer.readInt() == Constant.HEADER_FLAG) {
						break;
					}
					//未读到包头标识略过一个字节
					buffer.resetReaderIndex();
					buffer.readByte();
					
					//不满足
					if(buffer.readableBytes() < BASE_LENTH){
						return ;
					}
				}
				//读取命令号
				int module = buffer.readInt();
				int cmd = buffer.readInt();
				
				//读取数据长度 
				int lenth = buffer.readInt();
				if(lenth < 0 ){
					ctx.channel().close();
				}
				
				//数据包还没到齐
				if(buffer.readableBytes() < lenth){
					buffer.readerIndex(beginIndex);
					return ;
				}
				
				//读数据部分
				byte[] data = new byte[lenth];
				buffer.readBytes(data);
				
				System.out.println("data-str-server:"+new String(data));
				
				RequestMsg message = new RequestMsg();
				message.setModule(module);
				message.setCmd(cmd);
				message.setData(data);
				//解析出消息对象,继续往下面的handler传递
				out.add(message);
			}else{
				break;
			}
		}
		
		//数据不完整,等待完整的数据包
		return ;
	
	}
}
/**
 * 
 */
package com.a.server;

import com.a.ResponseMsg;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * 
 * +---------------------------------------------------------------------------
 * | 包头(int)4 | 模块(int)4  | 命令(int)4  |  结果码 (int)4   | 数据长度(int)4  | ......
 * +---------------------------------------------------------------------------
 * 
 * 编码返回
 */
public class ZukServerResponseEncoder extends MessageToByteEncoder<ResponseMsg>{

	@Override
	protected void encode(ChannelHandlerContext ctx, ResponseMsg response, ByteBuf buffer)
			throws Exception {
		
		System.out.println("返回请求:" + "module:" +response.getModule() +" cmd:" + response.getCmd() + " code:" + response.getCode());
		
		//包头
		buffer.writeInt(123456789);
		//module
		buffer.writeInt(response.getModule());
		//cmd
		buffer.writeInt(response.getCmd());
		//结果码
		buffer.writeInt(200);
		//长度
		int lenth = response.getData()==null? 0 : response.getData().length;
		if(lenth <= 0){
			buffer.writeInt(lenth);
		}else{
			buffer.writeInt(lenth);
			buffer.writeBytes(response.getData());
		}
	
		
	} 
	
}
/**
 * 
 */
package com.a.server;

import java.nio.charset.Charset;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.a.RequestMsg;
import com.a.ResponseMsg;
import com.alibaba.fastjson.JSON;

/**
 *
 */
public class ZukServerHandler  extends SimpleChannelInboundHandler<RequestMsg> {

	private Logger logger = LoggerFactory.getLogger(ZukServerHandler.class);
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, RequestMsg msg)
			throws Exception {
		
		System.out.println("msg:"+JSON.toJSONString(msg));
		ResponseMsg response =  new ResponseMsg();
		response.setCmd(msg.getCmd());
		response.setModule(msg.getModule());
		response.setCode(200);
		Charset charset = Charset.forName("UTF-8");
		response.setData(("hi,"+new String(msg.getData(),charset)+"i'm form server.").getBytes(charset));

		Channel channel = ctx.channel();
		channel.writeAndFlush(response);
		
	}
	
	
	 
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("channelInactive断开连接");
//		Session session = new SessionImpl(ctx.channel());
//		Object object = session.getAttachment();
//		if(object != null){
//			Player player = (Player)object;
//			SessionManager.removeSession(player.getPlayerId());
//		}
	}

}

客户端Netty:

/**
 * 
 */
package com.a.clientSocket;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
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;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import com.a.RequestMsg;

public class ZukClient {

	public static void main(String[] args) throws Exception {
		
		Bootstrap bootstrap = new Bootstrap();
		
		EventLoopGroup group = new NioEventLoopGroup();
		bootstrap.group(group);
		
		bootstrap.channel(NioSocketChannel.class);
		
		bootstrap.handler(new ChannelInitializer<SocketChannel>() {
			@Override
			public void initChannel(SocketChannel ch) throws Exception {
				ch.pipeline().addLast(new ZukClientResponseDecoder());
				ch.pipeline().addLast(new ZukClientRequestEncoder());
				ch.pipeline().addLast(new ZukClientHandler());
			}
		});
		
		// 连接服务端
		ChannelFuture connect = bootstrap.connect(new InetSocketAddress("127.0.0.1", 10102));
		connect.sync();
		Channel channel = connect.channel();
		
		int i = 0;
		while(i++<2){
			
			Thread.sleep(1000);
			String str = "平安金融中心-pafc-"+i;
			
			RequestMsg msg = new RequestMsg();
			msg.setCmd(i+100);
			msg.setModule(i+1000);
			Charset charset = Charset.forName("UTF-8");
			msg.setData(str.getBytes(charset));
			channel.writeAndFlush(msg);
		}

//		Thread.sleep(2000);
		channel.close();
		
	}
	
}
/**
 * 
 */
package com.a.clientSocket;

import java.nio.charset.Charset;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import com.a.ResponseMsg;
import com.alibaba.fastjson.JSON;

/**
 *
 */
public class ZukClientHandler extends SimpleChannelInboundHandler<ResponseMsg> {

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, ResponseMsg msg)
			throws Exception {
		System.out.println("ZukClientHandler.msg:"+JSON.toJSONString(msg));
		System.out.println("code:"+msg.getCode());
		System.out.println("module:"+msg.getModule());
		System.out.println("cmd:"+msg.getCmd());
		System.out.println("len:"+msg.getData().length);
		Charset charset = Charset.forName("UTF-8");
		System.out.println("str:"+new String(msg.getData(), charset));
	}

}
package com.a.clientSocket;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

import com.a.ResponseMsg;
 
public class ZukClientResponseDecoder extends ByteToMessageDecoder{
	
	/**
	 * 数据包基本长度
	 */
	public static int BASE_LENTH = 4 + 2 + 2 + 4 + 4;

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
		
		System.out.println("ZukClientResponseDecoder.decode");
		
		while(true){
			if(buffer.readableBytes() >= BASE_LENTH){
				//第一个可读数据包的起始位置
				int beginIndex;
				
				while(true) {
					//包头开始游标点
					beginIndex = buffer.readerIndex();
					//标记初始读游标位置
					buffer.markReaderIndex();
					if (buffer.readInt() == 123456789) {
						break;
					}
					//未读到包头标识略过一个字节
					buffer.resetReaderIndex();
					buffer.readByte();
					
					//不满足
					if(buffer.readableBytes() < BASE_LENTH){
						return ;
					}
				}
				//读取模块号命令号
				int module = buffer.readInt();
				int cmd = buffer.readInt();
				
				int stateCode = buffer.readInt();
				
				//读取数据长度 
				int lenth = buffer.readInt();
				if(lenth < 0 ){
					ctx.channel().close();
				}
				
				//数据包还没到齐
				if(buffer.readableBytes() < lenth){
					buffer.readerIndex(beginIndex);
					return ;
				}
				
				//读数据部分
				byte[] data = new byte[lenth];
				buffer.readBytes(data);
				
				ResponseMsg response = new ResponseMsg();
				response.setModule(module);
				response.setCmd(cmd);	
				response.setCode(stateCode);
				response.setData(data);
				//解析出消息对象,继续往下面的handler传递
				out.add(response);
			}else{
				break;
			}
		}
		//数据不完整,等待完整的数据包
	
		System.out.println("end.");
		
		return ;
	}

}
package com.a.clientSocket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import com.a.RequestMsg;
import com.alibaba.fastjson.JSON;
 
public class ZukClientRequestEncoder extends MessageToByteEncoder<RequestMsg>{

	@Override
	protected void encode(ChannelHandlerContext ctx, RequestMsg message, ByteBuf buffer) throws Exception {

		System.out.println("ZukClientRequestEncoder.编码:"+JSON.toJSONString(message));
		
		//包头
		buffer.writeInt(123456789);
		//module
		buffer.writeInt(message.getModule());
		//cmd
		buffer.writeInt(message.getCmd());
		//长度
		int lenth = message.getData()==null? 0 : message.getData().length;
		if(lenth <= 0){
			buffer.writeInt(lenth);
		}else{
			buffer.writeInt(lenth);
			buffer.writeBytes(message.getData());
		}
	}
}

socket客户端

/**
 * 
 */
package com.a.clientNetty;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;

/**
 *
 */
public class socket {


    /**
     * Socket客户端
     */
    public static void main(String[] args) {
        try {
            //创建Socket对象
            Socket socket=new Socket("localhost",10102);
            
            //根据输入输出流和服务端连接
            OutputStream outputStream=socket.getOutputStream();//获取一个输出流,向服务端发送信息
            
            DataOutputStream buffer = new DataOutputStream(outputStream);
            
            //包头
    		buffer.writeInt(123456789);
    		//module
    		buffer.writeInt(100);
    		//cmd
    		buffer.writeInt(1000);
    		String str = "hello 平安.";
    		//长度
    		Charset charset = Charset.forName("UTF-8");
    		byte[] data  = str.getBytes(charset); 
    		int lenth = data.length;
    		if(lenth <= 0){
    			buffer.writeInt(lenth);
    		}else{
    			buffer.writeInt(lenth);
    			buffer.write(data);
    		}
    		
    		
            InputStream inputStream=socket.getInputStream();//获取一个输入流,接收服务端的信息
            
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            int header = dataInputStream.readInt();
            int module = dataInputStream.readInt();
            int cmd = dataInputStream.readInt();
            int code = dataInputStream.readInt();
            int len = dataInputStream.readInt();
            byte[] b = new byte[len];
			dataInputStream.read(b);
			System.out.println("header:"+header);
			System.out.println("module:"+module);
			System.out.println("cmd:"+cmd);
			System.out.println("code:"+code);
			System.out.println("len:"+len);
			System.out.println("str:"+new String(b,charset));
            
//            //关闭相对应的资源
//            bufferedReader.close();
//            inputStream.close();
//            outputStream.close();
//            buffer.flush();
//    		buffer.close();
//            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

猜你喜欢

转载自blog.csdn.net/qq5132834/article/details/85242388
今日推荐