最近在做一个项目,基于android版本的一个物联网应用,涉及到了关于socket通信方面的内容,在google上搜了一下,发现Netty框架可以快速的实现socket通信。而且使用起来十分方便。
1.建立socket连接
public class CmdClient { private ClientBootstrap bootstrap; private ChannelFuture channelFuture; private Channel channel; private static final CmdClient client = new CmdClient(); //单例实现,用来取channel private CmdClient(){ } public static CmdClient getInstance(){ return client; } public Channel getChannel() { return channel; } public void setChannel(Channel channel) { this.channel = channel; } public ClientBootstrap getBootstrap() { return bootstrap; } public void setBootstrap(ClientBootstrap bootstrap) { this.bootstrap = bootstrap; } public ChannelFuture getChannelFuture() { return channelFuture; } public void setChannelFuture(ChannelFuture channelFuture) { this.channelFuture = channelFuture; } public int start(String ip,int port) { System.setProperty("java.net.preferIPv4Stack", "true"); System.setProperty("java.net.preferIPv6Addresses", "false"); bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); bootstrap.setPipelineFactory(new CmdPipelineFactory()); bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("keepAlive", true); channelFuture = bootstrap.connect(new InetSocketAddress(ip, port)); channelFuture.awaitUninterruptibly(); channel = channelFuture.awaitUninterruptibly().getChannel(); return 1; } public void stop() { channelFuture.awaitUninterruptibly(); if (!channelFuture.isSuccess()) { channelFuture.getCause().printStackTrace(); } channelFuture.getChannel().getCloseFuture().awaitUninterruptibly(); bootstrap.releaseExternalResources(); }
2.CmdPipelineFactory代码
public class CmdPipelineFactory implements ChannelPipelineFactory { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("cmdDecoder", new CmdDecoder()); pipeline.addLast("handler", new CmdClientHandler()); return pipeline; } }
3.netty使用的是filter方式实现packet解析,这边我加入了一个CmdDecoder用来解析协议包头
public class CmdDecoder extends FrameDecoder {
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer) throws Exception {
if (buffer.readableBytes() < 1) {
return null;
}
buffer.markReaderIndex();
ChannelBuffer magicBuff = buffer.readBytes(1);
int magic = DataConvert.byteArrayToSignedInt(magicBuff
.array());
if (magic == 0x77) {
if (buffer.readableBytes() < 19) {
return null;
}
buffer.markReaderIndex();
ChannelBuffer lenBuff = buffer.readBytes(19);
PacketParse parse = new PacketParse(null);
byte[] lenByte = parse.getPackForTwoByte(lenBuff.array(), 17, 2);
int len = DataConvert.byteArrayToSignedInt(lenByte);
if (buffer.readableBytes() < len) {
buffer.resetReaderIndex();
return null;
}
ChannelBuffer frame = buffer.readBytes(len);
return frame;
}
buffer.clear();
return null;
}
这个需要根据自己所定义的协议来处理