netty学习三:基于socket的聊天小demo
2017-07-30 12:53
459 查看
服务端代码
客户端代码
当有新的客户端连接到服务器的时候,ChatServerHandler的channelRead0方法会给所有上线的客户端发送消息。
ChatClient的main方法中,会从System.in中获取用户的输入,并写到服务端。
csdn code 路径
这个项目的源代码放置在csdn code上,欢迎访问。
netty_study
package chat.server; 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 ChatServer { public static void main(String[] args) throws InterruptedException { // 接收连接,但是不处理 EventLoopGroup parentGroup = new NioEventLoopGroup(); // 真正处理连接的group EventLoopGroup childGroup = new NioEventLoopGroup(); try { //加载Initializer ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(parentGroup, childGroup) .channel(NioServerSocketChannel.class) //这里的childHandler是服务于childGroup的,如果直接使用 //handler方法添加处理器,则是服务于parentGroup的 .childHandler(new ChatServerInitializer()); //绑定监听端口 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); } finally { parentGroup.shutdownGracefully(); childGroup.shutdownGracefully(); } } } package chat.server; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; public class ChatServerInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //1、按照分隔符切割消息 pipeline.addLast(new DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter())); //2、socket编程中需要对字符串进行编码解码 pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new ChatServerHandler()); } } package chat.server; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.GlobalEventExecutor; public class ChatServerHandler extends SimpleChannelInboundHandler<String>{ //存放所有channel对象 private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { Channel channel = ctx.channel(); channelGroup.forEach(ch -> { if (channel != ch) { ch.writeAndFlush(channel.remoteAddress()+" 发送的:"+msg+"\n"); } else { ch.writeAndFlush("本人发的消息:"+msg + "\n"); } }); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); channelGroup.writeAndFlush("有人:"+channel.remoteAddress()+"加入\n"); channelGroup.add(channel); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); channelGroup.writeAndFlush("有人:"+channel.remoteAddress()+"离开\n"); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); System.out.println(channel.remoteAddress() + "上线"); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { Channel channel = ctx.channel(); System.out.println(channel.remoteAddress() + "上线"); } }
客户端代码
package chat.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; public class ChatClient { public static void main(String[] args) throws InterruptedException, IOException { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { //加载Initializer Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup) .channel(NioSocketChannel.class) .handler(new ChatClientInitializer()); //连接服务端 Channel channel = bootstrap.connect("localhost", 8899).sync().channel(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); for(;;) { channel.writeAndFlush(br.readLine() + "\r\n"); } } finally { eventLoopGroup.shutdownGracefully(); } } } package chat.client; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; public class ChatClientInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //1、按照分隔符切割消息 pipeline.addLast(new DelimiterBasedFrameDecoder(4096,Delimiters.lineDelimiter())); //2、socket编程中需要对字符串进行编码解码 pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); //3、添加自定义处理器 pipeline.addLast(new ChatClientHandler()); } } package chat.client; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; public class ChatClientHandler extends SimpleChannelInboundHandler<String>{ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); } }
当有新的客户端连接到服务器的时候,ChatServerHandler的channelRead0方法会给所有上线的客户端发送消息。
ChatClient的main方法中,会从System.in中获取用户的输入,并写到服务端。
csdn code 路径
这个项目的源代码放置在csdn code上,欢迎访问。
netty_study
相关文章推荐
- netty学习二:基于socket通讯的小demo
- 【Java学习】基于Socket的多用户聊天Demo
- 基于Node.js + socket.io实现WebSocket的聊天DEMO
- 基于Netty的文件上传下载、心跳检测、在线聊天的demo
- 基于socket的客户端和服务端聊天简单使用 附Demo
- 一个基于netty的websocket聊天demo
- 详解基于java的Socket聊天程序――客户端(附demo)
- 详解基于java的Socket聊天程序――初始设计(附demo)
- 详解基于java的Socket聊天程序——客户端(附demo)
- osgi实战学习之路:5.生命周期及利用命令、装饰者模式实现基于socket交互Bundle命令demo
- 详解基于java的Socket聊天程序——服务端(附demo)
- osgi实战学习之路:5.生命周期及利用命令、装饰者模式实现基于socket交互Bundle命令demo
- android学习日记——基于UDP的聊天demo
- 详解基于java的Socket聊天程序――服务端(附demo)
- 菜鸟学习nodejs--Socket.IO二(聊天服务器)
- 【局域网聊天客户端篇】基于socket与Qt
- Socket(二)基于InputStream和OutputStream实现多人聊天功能
- 基于socket和thread写的入门级简易聊天工具
- 基于Linux的SOCKET编程之TCP半双工Client-Server聊天程序
- [java]基于UDP的Socket通信Demo