在android中使用netty框架通信
??? 最近在做一个项目,基于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(); //单例实现,用来取channelprivate 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 {@Overridepublic 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;
??? }
这个需要根据自己所定义的协议来处理
1 楼 冲杯茶喝 2012-08-01 bootstrap.setOption("reuseAddress", true);