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

本文详细介绍了网络通信中使用的特定协议,包括请求和响应的结构,以及编解码代码实现。服务端和客户端代码展示了如何使用这些协议进行网络交互。通过编码和解码过程,确保了数据在不同端点之间的正确传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、协议

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();

 

 

 

 

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值