SocketIO---Netty--HelloWorld

1. server

 1 public class Server {
 2 
 3     public static void main(String[] args) throws Exception {
 4         System.out.println("Server is starting...");
 5         //1 创建线两个程组 
 6         EventLoopGroup bossGroup = new NioEventLoopGroup(); //一个是用于处理服务器端接收客户端连接的
 7         EventLoopGroup workGroup = new NioEventLoopGroup();    //一个是进行网络通信的(网络读写的)
 8         
 9         //2 创建辅助工具类,用于服务器通道的一系列配置
10         ServerBootstrap b = new ServerBootstrap();
11         b.group(bossGroup, workGroup)        //绑定俩个线程组
12         .channel(NioServerSocketChannel.class)        //指定NIO的模式
13         .option(ChannelOption.SO_BACKLOG, 1024)        //设置tcp缓冲区
14         .option(ChannelOption.SO_SNDBUF, 32*1024)    //设置发送缓冲大小
15         .option(ChannelOption.SO_RCVBUF, 32*1024)    //这是接收缓冲大小
16         .option(ChannelOption.SO_KEEPALIVE, true)    //保持连接
17         .childHandler(new ChannelInitializer<SocketChannel>() {//服务端就是childHandler
18             @Override
19             protected void initChannel(SocketChannel socketChannel) throws Exception {
20                 //3 在这里配置具体数据接收方法的处理 ChannelPipeline<<<添加到<<-ChannelHandler
21                 socketChannel.pipeline().addLast(new ServerHandler());
22             }
23         });
24         
25         //4 异步,进行绑定  服务端是bind,客户端是connect
26         ChannelFuture channelFuture = b.bind(8765).sync();
27         //5 等待关闭
28         channelFuture.channel().closeFuture().sync(); // 阻塞用, 等价于Thread.sleep(Integer.MAX_VALUE)
29         
30         bossGroup.shutdownGracefully();
31         workGroup.shutdownGracefully();
32     }
33 }
View Code

1.2 ServerHandler

 1 //服务端业务逻辑处理类
 2 public class ServerHandler extends ChannelHandlerAdapter {
 3     @Override
 4     public void channelActive(ChannelHandlerContext ctx) throws Exception {
 5         System.out.println("server channel active... ");
 6     }
 7     
 8     @Override //Object msg 服务端接收到的客户端请求的数据封装到object对象中
 9     public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
10             ByteBuf buf = (ByteBuf) msg;
11             byte[] req = new byte[buf.readableBytes()];
12             buf.readBytes(req);//先读到字节数组中
13             String body = new String(req, "utf-8");
14             System.out.println("Server接收到客户端请求:"+body);
15             String response = "Hi Client, I am Server! you send " + body+"to me???" ;
16             //Unpooled.copiedBuffer(response.getBytes()将string-->byte[]--->ByteBuf
17             ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes())); 
18             //.addListener(ChannelFutureListener.CLOSE);
19     }
20 
21     @Override
22     public void channelReadComplete(ChannelHandlerContext ctx)throws Exception {
23         System.out.println("读完了");
24         ctx.flush();
25     }
26 
27     @Override
28     public void exceptionCaught(ChannelHandlerContext ctx, Throwable t)throws Exception {
29         ctx.close();
30     }
31 
32 }
View Code

2. client

 1 public class Client {
 2     public static void main(String[] args) throws Exception{
 3         System.out.println("Client is Starting...");
 4         EventLoopGroup group = new NioEventLoopGroup();//客户端一个线程组,发送请求即可
 5         Bootstrap b = new Bootstrap(); //辅助类, 服务端为ServerBootstrap
 6         b.group(group)
 7         .channel(NioSocketChannel.class)
 8         .handler(new ChannelInitializer<SocketChannel>() {//服务端为childHandler(...)
 9             @Override
10             protected void initChannel(SocketChannel socketChannel) throws Exception { 
11                 socketChannel.pipeline().addLast(new ClientHandler());//ChannelPipeline.addLast
12             }
13         });
14         
15         ChannelFuture channelFuture = b.connect("127.0.0.1", 8765).sync();
16         //发送消息
17         Thread.sleep(1000);
18         channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("Client: Hi Server, I am client netty!".getBytes()));
19         channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("client request 666".getBytes()));
20         Thread.sleep(2000);
21         channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("client request 888".getBytes()));
22         
23         channelFuture.channel().closeFuture().sync();//阻塞
24         group.shutdownGracefully();
25     }
26 }
View Code

3. ClientHandler

 1 //客户端业务处理类
 2 public class ClientHandler extends ChannelHandlerAdapter{
 3     @Override
 4     public void channelActive(ChannelHandlerContext ctx) throws Exception {
 5     }
 6 
 7     @Override //Object msg 客户端接收到的服务端响应的数据封装为object对象
 8     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 9         try {
10             ByteBuf buf = (ByteBuf) msg;
11             byte[] req = new byte[buf.readableBytes()]; //创建一个字节数组
12             buf.readBytes(req); //把数据先读到字节数组中
13             String body = new String(req, "utf-8");
14             String response = "Client: 收到服务器端的返回信息:" + body;
15             System.out.println(response);
16         } finally {
17             ReferenceCountUtil.release(msg); //服务端在writeAndFlush的时候自动释放了, 客户端没调用write方法需要手动释放
18         }
19     }
20 
21     @Override
22     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
23 
24     }
25 
26     @Override
27     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
28             throws Exception {
29         ctx.close();
30     }
31 
32 }
View Code
 1 结果:
 2 Client is Starting...
 3 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send Client: Hi Server, I am client netty!client request 666to me???
 4 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send client request 888to me???
 5 
 6 -------------------------------------------------------
 7 
 8 Server is starting...
 9 server channel active... 
10 Server接收到客户端请求:Client: Hi Server, I am client netty!client request 666
11 读完了
12 Server接收到客户端请求:client request 888
13 读完了
View Code

 

4. 如果想单次连接后得到响应,就关闭客户端,必须在server端关闭.   .addListener(ChannelFutureListener.CLOSE)

 1 //服务端业务逻辑处理类
 2 public class ServerHandler extends ChannelHandlerAdapter {
 3     @Override
 4     public void channelActive(ChannelHandlerContext ctx) throws Exception {
 5         System.out.println("server channel active... ");
 6     }
 7     
 8     @Override //Object msg 服务端接收到的客户端请求的数据封装到object对象中
 9     public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
10             ByteBuf buf = (ByteBuf) msg;
11             byte[] req = new byte[buf.readableBytes()];
12             buf.readBytes(req);//先读到字节数组中
13             String body = new String(req, "utf-8");
14             System.out.println("Server接收到客户端请求:"+body);
15             String response = "Hi Client, I am Server! you send " + body+"to me???" ;
16             //Unpooled.copiedBuffer(response.getBytes()将string-->byte[]--->ByteBuf
17             ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes())) 
18             .addListener(ChannelFutureListener.CLOSE);//关闭通道必须在Server端,一次连接后就关闭
19     }
20 
21     @Override
22     public void channelReadComplete(ChannelHandlerContext ctx)throws Exception {
23         System.out.println("读完了");
24         ctx.flush();
25     }
26 
27     @Override
28     public void exceptionCaught(ChannelHandlerContext ctx, Throwable t)throws Exception {
29         ctx.close();
30     }
31 
32 }
View Code

效果: 客户端只能收到服务器端一条响应

1 Client is Starting...
2 Client: 收到服务器端的返回信息:Hi Client, I am Server! you send Client: Hi Server, I am client netty!client request 666to me???
View Code

 

posted @ 2017-12-14 20:52  黑土白云  阅读(1105)  评论(0编辑  收藏  举报