Netty学习笔记(一)二进制流协议【转】

一、协议

1. 请求:

 

字段

类型

说明

length

short

消息长度

commandid

short

消息类型

userid

int

用户号

2. 响应:

 

 

字段

类型

说明

length

short

消息长度

commandid

short

消息类型

userid

int

用户号

result

byte

0: 成功

1: 失败

二、编解码代码

public abstract class KaMessage {

 

protected short commandId;

 

 

protected int userId;

 

public static final short HEADLENGTH = 6;

 

public static final short REQ = 0x0001;

 

public static final short RES = 0x1001;

 

 

 

 

public void encode(ByteBuffer buffer) {

buffer.putInt(userId);

subencode(buffer);

}

 

public void decode(ByteBuffer buffer) {

userId = buffer.getInt();

subdecode(buffer);

}

 

public abstract short length();

 

public abstract void subencode(ByteBuffer buffer);

 

public abstract void subdecode(ByteBuffer buffer);

 

public int getUserId() {

return userId;

}

 

public void setUserId(int userId) {

this.userId = userId;

}

 

public short getCommandId() {

return commandId;

}

}

 

public class KaRes extends KaMessage {

 

private short result = 200;

 

public KaRes() {

commandId = KaMessage.RES;

}

 

@Override

public short length() {

// TODO Auto-generated method stub

short len = KaMessage.HEADLENGTH;

len += 2;

return len;

}

 

@Override

public void subencode(ByteBuffer buffer) {

// TODO Auto-generated method stub

buffer.putShort(result);

}

 

@Override

public void subdecode(ByteBuffer buffer) {

// TODO Auto-generated method stub

result = buffer.getShort();

}

 

@Override

public String toString() {

// TODO Auto-generated method stub

StringBuffer sb = new StringBuffer();

sb.append(super.toString());

sb.append(" - result: " + result);

return sb.toString();

}

 

public short getResult() {

return result;

}

 

public void setResult(short result) {

this.result = result;

}

 

}

 


public class KaReq extends KaMessage {

 

 

 

 

public KaReq() {

commandId = KaMessage.REQ;

}

 

@Override

public void subencode(ByteBuffer buffer) {

// TODO Auto-generated method stub

}

 

@Override

public short length() {

// TODO Auto-generated method stub

short len = PaMessage.HEADLENGTH;

 

 

return len;

}

 

@Override

public void subdecode(ByteBuffer buffer) {

// TODO Auto-generated method stub

}

}

 

 

public class KaCodecUtil {

 

public static byte[] NetEncode(PaMessage message) {

ByteBuffer buffer = ByteBuffer.allocate(message.length() + 2);

buffer.putShort(message.length());

buffer.putShort(message.getCommandId());

message.encode(buffer);

return buffer.array();

}

 

public static KaMessage NetDecode(byte[] data) {

ByteBuffer buffer = ByteBuffer.wrap(data);

short commandId = buffer.getShort();

PaMessage message = null;

switch(commandId) {

case KaMessage.SEQ:

message = new KaReq();

message.decode(buffer);

return message;

case KaMessage.Res:

message = new KaRes();

message.decode(buffer);

return message;

 

 

}

return message;

}

 


public class KaEncoder extends OneToOneEncoder {

@Override

protected Object encode(ChannelHandlerContext context, Channel channel,

Object object) throws Exception {

// TODO Auto-generated method stub

KaMessage message = (KaMessage)object;

ChannelBuffer buf = ChannelBuffers.dynamicBuffer();

buf.writeBytes(KaCodecUtil.NetEncode(message));

return buf;

}

}

 

 

public class KaDecoder extends FrameDecoder {

 

@Override

protected Object decode(ChannelHandlerContext context, Channel channel,

ChannelBuffer buffer) throws Exception {

// TODO Auto-generated method stub

if(buffer.readableBytes() < 2) {

buffer.resetReaderIndex();

return null;

}

short length = buffer.readShort();

if(buffer.readableBytes() < length) {

buffer.resetReaderIndex();

return null;

}

byte[] decode = new byte[length];

buffer.readBytes(decode);

KaMessage message = KaCodecUtil.NetDecode(decode);

return message;

}

 

}


二、服务端代码

public class ServerBoot {

 

public static void main(String[] args) {

ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {

 

 

public ChannelPipeline getPipeline() {

ChannelPipeline pipeline = Channels.pipeline();

pipeline.addLast("decoder", new KaDecoder());

pipeline.addLast("encoder", new KaEncoder());

pipeline.addLast("handler", new KaHandler());

return pipeline;

}

};

 

ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());

ServerBootstrap bootstrap = new ServerBootstrap(factory);

bootstrap.setPipelineFactory(pipelineFactory);

bootstrap.setOption("child.tcpNoDelay", true);

bootstrap.setOption("child.keepAlive", true);

bootstrap.bind(new InetSocketAddress(8080));

 

}

}

 

 

public class KaHandler extends SimpleChannelUpstreamHandler {

 

private static Logger log = Logger.getLogger(PaHandler.class);

 

@Override

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {

try {

KaMessage req = (KaMessage) e.getMessage();

log.info("messageReceived: " + req);

KaRes res = new KaRes();

e.getChannel().write(res);

}catch(Exception ee) {

ee.printStackTrace();

}

}

}

 

三、客户端代码

 

public class ServerBoot {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

 

ClientBootstrap bootstrap = new ClientBootstrap(

new NioClientSocketChannelFactory(

Executors.newCachedThreadPool(),

Executors.newCachedThreadPool()));

bootstrap.getPipeline().addLast("encoder", new KaEncoder());

bootstrap.getPipeline().addLast("decoder", new KaDecoder());

bootstrap.getPipeline().addLast("handler", new KaHandler());

ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));

 

future.awaitUninterruptibly();

Channel channel = future.getChannel();

KaReq req = new KaReq();

 

future = channel.write(req);

future.awaitUninterruptibly();

 

 

 

 

}

}

你可能感兴趣的:(netty)