[Android初级]android与netty4初体验

    博主曾经对netty4的helloword很感兴趣,也曾单纯的写过一个小小的聊天室java代码,现在重新来看看,浏览了这位牛人的博客 点击去看看

    我觉得受益匪浅,故拿来分享。

     这次是在android上使用netty作为客户端,来与服务端相互通讯的小事例,纯粹的helloworld,效果就是在android程序中发送一个消息到服务端,然后服务端也回一个消息给客户端,很简单的demo,.大牛看了可不要吐槽啊!

1.demo结构

[Android初级]android与netty4初体验_第1张图片

2.服务端代码:

Server.java

package org.jan.netty.demo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class MyHelloServer {

	private static final int PORT = 7878;

	public static void main(String[] args) {
		EventLoopGroup parentGroup = new NioEventLoopGroup();
		EventLoopGroup childrenGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap serverBootstrap = new ServerBootstrap();
			serverBootstrap.group(parentGroup, childrenGroup);
			serverBootstrap.channel(NioServerSocketChannel.class);
			//添加工作线程
			serverBootstrap.childHandler(new MyHelloServerInitializer());
			// 服务器绑定端口监听
			ChannelFuture cf = serverBootstrap.bind(PORT).sync();
			// 监听服务器关闭监听
			cf.channel().closeFuture().sync();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			parentGroup.shutdownGracefully();
			childrenGroup.shutdownGracefully();
		}
	}
}

MyHelloServerHandler.java

package org.jan.netty.demo;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.net.InetAddress;
import java.nio.charset.Charset;

public class MyHelloServerHanler extends SimpleChannelInboundHandler<String> {

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg)
			throws Exception {
		String recStr = new String(msg.getBytes(), Charset.forName("UTF-8"));
		//收到消息直接打印输出
		System.out.println(ctx.channel().remoteAddress()+" say :"+recStr);
		//返回客户端 
		ctx.writeAndFlush("Received your message!\n");
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("RamoteAddress: "+ctx.channel().remoteAddress()+" active!");
//		ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + "'s service!\n");
		ctx.writeAndFlush("我是服务端,我是服务端!\n");
		super.channelActive(ctx);
	}
}



3.android客户端代码:

/**
 * demo主界面:只有一个按钮发送消息
 * @author jan
 */
public class ClientActivity extends Activity {
	private static final String TAG = "MainActivity";
	private static Context context;
	public static int MSG_REC=0xabc;
	public static int PORT = 7878;
	public static final String HOST = "192.168.50.110";
	private NioEventLoopGroup group;
	private Button sendButton;
	private Channel mChannel;
	private ChannelFuture cf;
	private Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			if(msg.what==MSG_REC){
				Toast.makeText(context, msg.obj.toString(), 1000).show();
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context = this;
		connected();
		sendButton = (Button) findViewById(R.id.netty_send_button);
		sendButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				sendMessage();
			}
		});
	}

	// 连接到Socket服务端
	private void connected() {
		new Thread() {
			@Override
			public void run() {
				group = new NioEventLoopGroup();
				try {
					// Client服务启动器 3.x的ClientBootstrap
					// 改为Bootstrap,且构造函数变化很大,这里用无参构造。
					Bootstrap bootstrap = new Bootstrap();
					// 指定EventLoopGroup
					bootstrap.group(group);
					// 指定channel类型
					bootstrap.channel(NioSocketChannel.class);
					// 指定Handler
					bootstrap.handler(new MyClientInitializer(context,mHandler));
					bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
					bootstrap.option(ChannelOption.TCP_NODELAY, true);
					bootstrap.option(ChannelOption.SO_TIMEOUT, 5000);
					// 连接到本地的7878端口的服务端
					cf = bootstrap.connect(new InetSocketAddress(
							HOST, PORT));
					mChannel = cf.sync().channel();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
	//发送数据
	private void sendMessage() {
		mHandler.post(new Runnable() {
			@Override
			public void run() {
				try {
					Log.i(TAG, "mChannel.write sth & " + mChannel.isOpen());
					mChannel.writeAndFlush("hello,this message is from client.\r\n");
					mChannel.read();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (group != null) {
			group.shutdownGracefully();
		}
	}

}

4.客户端中 bootstrap的初始化类MyClientInitializer.java

public class MyClientInitializer extends ChannelInitializer<SocketChannel> {
	private Context context;
	private Handler handler;
	public MyClientInitializer(Context ctx,Handler handler){
		this.context = ctx;
		this.handler = handler;
	}
	
	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		/**
		 * 这个地方的必须和服务端对应上。否则无法正常解码和编码
		 */
		pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
		pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
		pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
		//客户端的逻辑
		pipeline.addLast("handler",new MyClientHandler(context,handler));
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		System.out.println("---channelRead--- msg="+msg);
		super.channelRead(ctx, msg);
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		System.out.println("---channelReadComplete---");
		super.channelReadComplete(ctx);
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		Log.i("MyClientInitializer","---channelActive---");
		super.channelActive(ctx);
	}
	
}
5.对应的数据处理类 ,没有什么新鲜性的东西哦。MyClientHandler.java

public class MyClientHandler extends SimpleChannelInboundHandler<String> {
	private Context ctx;
	private Handler handler;

	public MyClientHandler(Context context, Handler handler) {
		this.ctx = context;
		this.handler = handler;
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String msg)
			throws Exception {
		Log.d("MyHelloClientHandler", "channelRead0->msg="+msg);
		Message m = new Message();
		m.what = ClientActivity.MSG_REC;
		m.obj = msg;
		handler.sendMessage(m);
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("Client active");
		super.channelActive(ctx);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("Client close ");
		super.channelInactive(ctx);
	}

}

实现效果:


去下载demo

你可能感兴趣的:(java,android,netty4)