基于netty 的android Socket 聊天室客户端
16lz
2021-01-23
废话不多说,直接上代码
MainActivity.java 主页面
importjava.net.InetSocketAddress;importio.netty.bootstrap.Bootstrap;importio.netty.channel.Channel;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelOption;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.nio.NioSocketChannel;importandroid.app.Activity;importandroid.content.BroadcastReceiver;importandroid.content.Context;importandroid.content.Intent;importandroid.content.IntentFilter;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Message;importandroid.util.Log;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.TextView;importandroid.widget.Toast;publicclassMainActivityextendsActivity{privatestaticfinalStringTAG="TAG";publicstaticintMSG_REC=0xabc;publicstaticfinalStringHOST="192.168.2.219";publicstaticintPORT=9103;privateNioEventLoopGroupgroup;privateChannelmChannel;privateChannelFuturecf;privatestaticContextcontext;privateTextViewtv;privateButtonbtn;privateHandlermHandler=newHandler(){@OverridepublicvoidhandleMessage(Messagemsg){if(msg.what==MSG_REC){Toast.makeText(context,msg.obj.toString(),0).show();}}};@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);context=this;connected();tv=(TextView)findViewById(R.id.iv);btn=(Button)findViewById(R.id.btn);btn.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){sendMessage();}});}//连接到Socket服务端privatevoidconnected(){newThread(){@Overridepublicvoidrun(){group=newNioEventLoopGroup();try{//Client服务启动器3.x的ClientBootstrap//改为Bootstrap,且构造函数变化很大,这里用无参构造。Bootstrapbootstrap=newBootstrap();//指定EventLoopGroupbootstrap.group(group);//指定channel类型bootstrap.channel(NioSocketChannel.class);//指定Handlerbootstrap.handler(newMyClientInitializer(MainActivity.this));//如果没有数据,这个可以注释看看bootstrap.option(ChannelOption.SO_KEEPALIVE,true);bootstrap.option(ChannelOption.TCP_NODELAY,true);//连接到本地的7878端口的服务端cf=bootstrap.connect(newInetSocketAddress(HOST,PORT));mChannel=cf.sync().channel();}catch(Exceptione){e.printStackTrace();}}}.start();}//发送数据privatevoidsendMessage(){mHandler.post(newRunnable(){@Overridepublicvoidrun(){try{Log.i(TAG,"mChannel.writesth&"+mChannel.isOpen());mChannel.writeAndFlush("我是android客户端");mChannel.read();}catch(Exceptione){e.printStackTrace();}}});}@OverrideprotectedvoidonDestroy(){super.onDestroy();if(group!=null){group.shutdownGracefully();}}}
MyClientHandler.java
importandroid.content.Context;importandroid.content.Intent;importandroid.os.Handler;importandroid.os.Message;importandroid.util.Log;importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelHandlerAdapter;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.SimpleChannelInboundHandler;publicclassMyClientHandlerextendsSimpleChannelInboundHandler<String>{privateContextcontext;publicMyClientHandler(Contextcontext){this.context=context;}@OverrideprotectedvoidchannelRead0(ChannelHandlerContextctx,Stringmsg)throwsException{Log.d("MyHelloClientHandler","channelRead0->msg="+msg);}@OverridepublicvoidchannelActive(ChannelHandlerContextctx)throwsException{System.out.println("Clientactive");super.channelActive(ctx);}@OverridepublicvoidchannelInactive(ChannelHandlerContextctx)throwsException{System.out.println("Clientclose");super.channelInactive(ctx);}}
MyClientInitializer.java
importandroid.content.Context;importandroid.os.Handler;importandroid.util.Log;importio.netty.channel.Channel;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelPipeline;importio.netty.channel.socket.SocketChannel;importio.netty.handler.codec.DelimiterBasedFrameDecoder;importio.netty.handler.codec.Delimiters;importio.netty.handler.codec.string.StringDecoder;importio.netty.handler.codec.string.StringEncoder;importio.netty.util.CharsetUtil;publicclassMyClientInitializerextendsChannelInitializer<SocketChannel>{privateContextcontext;publicMyClientInitializer(Contextctx){this.context=ctx;}@OverrideprotectedvoidinitChannel(SocketChannelch)throwsException{ChannelPipelinepipeline=ch.pipeline();/***这个地方的必须和服务端对应上。否则无法正常解码和编码*///pipeline.addLast("framer",newDelimiterBasedFrameDecoder(8192,//Delimiters.lineDelimiter()));//这个是解决沾包的问题,但是我发现加上这句话,就读取不到返回值,不知道为什么pipeline.addLast("decoder",newStringDecoder(CharsetUtil.UTF_8));pipeline.addLast("encoder",newStringEncoder(CharsetUtil.UTF_8));//客户端的逻辑pipeline.addLast("handler",newMyClientHandler(context));}@OverridepublicvoidchannelRead(ChannelHandlerContextctx,Objectmsg)throwsException{System.out.println("---channelRead---msg="+msg);super.channelRead(ctx,msg);}@OverridepublicvoidchannelReadComplete(ChannelHandlerContextctx)throwsException{System.out.println("---channelReadComplete---");super.channelReadComplete(ctx);}@OverridepublicvoidchannelActive(ChannelHandlerContextctx)throwsException{Log.i("MyClientInitializer","---channelActive---");super.channelActive(ctx);}}
既然是网络通信,肯定得加上网络权限
<uses-permissionandroid:name="android.permission.INTERNET"/>
要加上netty4 的jar
下载地址:http://netty.io/downloads.html
更多相关文章
- android 客户端发送http访问服务器端,网络检测
- 闲来无事,分析一下淘宝千牛客户端
- Android异步Http客户端 一个基于回调的Http客户端库为Android
- Android 发送JSON数据到服务端
- Android 仿网易一元夺宝客户端下拉加载动画实现(一)
- 手机淘宝Android客户端架构
- 南青信息查询 for Android客户端
- Android客户端与服务器端交互,如何保持session回话