一、实例要求

1、编写一个netty群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞)
2、实现多人群聊
3、服务器端:可以检测用户上线,离线,并实现消息转发功能
4、客户端:通过channel可以无阻塞发送消息给其他所有用户,同时可以接受其他用户发送的消息(由服务器转发得到)
5、目的:进一步理解netty非阻塞网络编程机制

二、服务端

1、GroupChatServer.java

package netty.groupchat;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;public class GroupChatServer {private int port; //监听端口GroupChatServer(int port) {this.port = port;}//编写run方法,处理客户端的请求public void run() {//创建两个线程组EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup(); //默认cpu核数*2ServerBootstrap server = new ServerBootstrap();try {server.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//获取到pipelineChannelPipeline pipeline = ch.pipeline();//向pipeline加入解码器pipeline.addLast("decoder", new StringDecoder());//向pipeline加入编码器pipeline.addLast("encoder", new StringEncoder());//如果不加这个编码解码器的,无法直接传输字符串,应该只能处理ByteBuf而不能直接处理String//加入自己的业务处理handlerpipeline.addLast(new GroupChatServerHandler());}});System.out.println("netty 服务器启动......");//绑定一个端口并且同步,生成了一个ChannelFuture对象//启动服务器并绑定端口ChannelFuture cf = server.bind(port).sync();//对关闭事件进行监听cf.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args) {new GroupChatServer(7000).run();}
}

2、GroupChatServerHandler.java

package netty.groupchat;import java.text.SimpleDateFormat;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 GroupChatServerHandler extends SimpleChannelInboundHandler<String> {//定义一个channel组,管理所有的channel//GlobalEventExecutor.INSTANCE:是全局的事件执行器,是一个单例private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//handlerAdded表示当连接建立,一旦连接,第一个被执行的方法//将当前channel加入到channelGroup@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();//将该加入聊天的信息推送给其他在线的客户端/*** 该方法会将channelGroup中所有的channel遍历,并发送消息* 我们不需要自己遍历* 在channelGroup.add之前就不会发给自己了*/channelGroup.writeAndFlush(sdf.format(new java.util.Date()) + " [客户端] " + channel.remoteAddress() + " 加入聊天\n");//将该客户端加入channelGroupchannelGroup.add(channel);}//断开连接会被触发,将xxx客户端离开信息推送给当前在线的客户@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channelGroup.writeAndFlush(sdf.format(new java.util.Date()) + " [客户端] " + channel.remoteAddress() + " 离开聊天\n");System.out.println("当前channelGroup大小:" + channelGroup.size());}//表示channel处于活动状态,提示xxx上线@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println(ctx.channel().remoteAddress() + " 上线了~");}//表示channel处于不活动状态,提示xxx离线了@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println(ctx.channel().remoteAddress() + " 离线了~");}//读取数据,业务处理@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {//获取到当前channelChannel channel = ctx.channel();//这时我们遍历channelGroup,根据不同的情况,回送不同的消息channelGroup.forEach(ch -> {if (channel != ch) {//不是当前的channel,直接转发消息ch.writeAndFlush("[客户] " + channel.remoteAddress() + " 发送消息:" + msg + "\n");} else {//是自己,回显自己发送的消息给自己ch.writeAndFlush("[自己]发送了消息:" + msg + "\n");}});}//发生异常@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {//关闭通道ctx.close();}
}

三、客户端

1、GroupChatClient.java

package netty.groupchat;import java.util.Scanner;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;public class GroupChatClient {//属性private final String host;private final int port;GroupChatClient(String host, int port) {this.host = host;this.port = port;}public void run() {EventLoopGroup group = new NioEventLoopGroup();Scanner scanner = null;try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//得到pipelineChannelPipeline pipeline = ch.pipeline();//加入相关handlerpipeline.addLast("decoder", new StringDecoder());pipeline.addLast("encoder", new StringEncoder());//加入自定的handlerpipeline.addLast(new GroupChatClientHandler());}});ChannelFuture channelFuture = bootstrap.connect(host, port).sync();//得到channelChannel channel = channelFuture.channel();System.out.println("------" + channel.localAddress() + "------");//客户端需要输入信息,创建一个扫描器scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String msg = scanner.nextLine();//通过channel发送到服务器端channel.writeAndFlush(msg + "\r\n");}} catch (Exception e) {e.printStackTrace();} finally {group.shutdownGracefully();scanner.close();}}public static void main(String[] args) {new GroupChatClient("127.0.0.1", 7000).run();}
}

2、GroupChatClientHandler.java

package netty.groupchat;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println(msg.trim());}}

四、备注

连接建立:
handlerAdded() -> channelRegistered() -> channelActive()
连接断开:
channelInactive() -> channelUnregistered() -> handlerRemoved()
发生异常:
exceptionCaught()

netty封装的事件驱动真的很牛逼

重点:
服务端channelGroup遍历channel,handlerAdded/handlerRemoved事件
客户端获取channel在主线程中写操作,同时netty负责异步非阻塞处理读操作

五、执行情况

1、服务端日志

15:40:46.219 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
15:40:46.226 [main] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
15:40:46.257 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
15:40:46.257 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
15:40:46.271 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
15:40:46.271 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
15:40:46.294 [main] DEBUG io.netty.util.internal.PlatformDependent - Platform: Windows
15:40:46.297 [main] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
15:40:46.297 [main] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 8
15:40:46.300 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
15:40:46.301 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
15:40:46.302 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
15:40:46.302 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
15:40:46.304 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
15:40:46.304 [main] DEBUG io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
15:40:46.304 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
15:40:46.304 [main] DEBUG io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
15:40:46.305 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: C:\Users\sjcui\AppData\Local\Temp (java.io.tmpdir)
15:40:46.305 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
15:40:46.307 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 3767533568 bytes
15:40:46.308 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
15:40:46.309 [main] DEBUG io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
15:40:46.309 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
15:40:46.324 [main] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
netty 服务器启动......
15:40:46.888 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.processId: 9060 (auto-detected)
15:40:46.891 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
15:40:46.891 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
15:40:47.277 [main] DEBUG io.netty.util.NetUtil - Loopback interface: lo (Software Loopback Interface 1, 127.0.0.1)
15:40:47.289 [main] DEBUG io.netty.util.NetUtil - Failed to get SOMAXCONN from sysctl and file \proc\sys\net\core\somaxconn. Default: 200
15:40:47.665 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 00:50:56:ff:fe:c0:00:01 (auto-detected)
15:40:47.681 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
15:40:47.681 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 16
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 16
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
15:40:47.711 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
15:40:47.712 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
15:40:47.712 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
15:40:47.712 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
15:40:47.722 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
15:40:47.722 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
15:40:47.722 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
/127.0.0.1:59696 上线了~
15:41:22.169 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:41:22.169 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
15:41:22.169 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
15:41:22.169 [nioEventLoopGroup-3-2] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
/127.0.0.1:59730 上线了~
15:41:22.184 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
15:41:22.184 [nioEventLoopGroup-3-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:41:22.186 [nioEventLoopGroup-3-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@10d46905
/127.0.0.1:59767 上线了~
/127.0.0.1:59696 离线了~
当前channelGroup大小:2
/127.0.0.1:59730 离线了~
当前channelGroup大小:1
/127.0.0.1:59767 离线了~
当前channelGroup大小:0

2、客户端1日志

15:41:06.051 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
15:41:06.060 [main] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
15:41:06.083 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
15:41:06.083 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
15:41:06.094 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
15:41:06.094 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
15:41:06.117 [main] DEBUG io.netty.util.internal.PlatformDependent - Platform: Windows
15:41:06.121 [main] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
15:41:06.121 [main] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 8
15:41:06.124 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
15:41:06.125 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
15:41:06.126 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
15:41:06.127 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
15:41:06.128 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
15:41:06.128 [main] DEBUG io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
15:41:06.128 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
15:41:06.128 [main] DEBUG io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
15:41:06.129 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: C:\Users\sjcui\AppData\Local\Temp (java.io.tmpdir)
15:41:06.129 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
15:41:06.131 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 3767533568 bytes
15:41:06.131 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
15:41:06.133 [main] DEBUG io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
15:41:06.133 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
15:41:06.149 [main] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
15:41:06.658 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.processId: 22336 (auto-detected)
15:41:06.661 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
15:41:06.661 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
15:41:07.043 [main] DEBUG io.netty.util.NetUtil - Loopback interface: lo (Software Loopback Interface 1, 127.0.0.1)
15:41:07.043 [main] DEBUG io.netty.util.NetUtil - Failed to get SOMAXCONN from sysctl and file \proc\sys\net\core\somaxconn. Default: 200
15:41:07.428 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 00:50:56:ff:fe:c0:00:01 (auto-detected)
15:41:07.442 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
15:41:07.442 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
15:41:07.471 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 16
15:41:07.471 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 16
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
15:41:07.472 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
15:41:07.473 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
15:41:07.482 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
15:41:07.482 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
15:41:07.482 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
------/127.0.0.1:59696------
15:41:22.196 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:41:22.196 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
15:41:22.196 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
15:41:22.196 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:41:22.207 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
15:41:22.207 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:41:22.209 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@7148612a
2023-01-03 15:41:22 [客户端] /127.0.0.1:59730 加入聊天
2023-01-03 15:41:55 [客户端] /127.0.0.1:59767 加入聊天
[客户] /127.0.0.1:59767 发送消息:我是59767
你好,我是tom
[自己]发送了消息:你好,我是tom
[客户] /127.0.0.1:59730 发送消息:我是6666

3、客户端2日志

15:41:20.736 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
15:41:20.742 [main] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
15:41:20.765 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
15:41:20.765 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
15:41:20.776 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
15:41:20.776 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
15:41:20.801 [main] DEBUG io.netty.util.internal.PlatformDependent - Platform: Windows
15:41:20.803 [main] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
15:41:20.804 [main] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 8
15:41:20.806 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
15:41:20.808 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
15:41:20.808 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
15:41:20.809 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
15:41:20.811 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
15:41:20.811 [main] DEBUG io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
15:41:20.812 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
15:41:20.812 [main] DEBUG io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
15:41:20.813 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: C:\Users\sjcui\AppData\Local\Temp (java.io.tmpdir)
15:41:20.814 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
15:41:20.816 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 3767533568 bytes
15:41:20.816 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
15:41:20.818 [main] DEBUG io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
15:41:20.818 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
15:41:20.833 [main] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
15:41:21.282 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.processId: 22260 (auto-detected)
15:41:21.284 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
15:41:21.284 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
15:41:21.669 [main] DEBUG io.netty.util.NetUtil - Loopback interface: lo (Software Loopback Interface 1, 127.0.0.1)
15:41:21.670 [main] DEBUG io.netty.util.NetUtil - Failed to get SOMAXCONN from sysctl and file \proc\sys\net\core\somaxconn. Default: 200
15:41:22.059 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 00:50:56:ff:fe:c0:00:01 (auto-detected)
15:41:22.075 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
15:41:22.075 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 16
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 16
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
15:41:22.102 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
15:41:22.103 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
15:41:22.103 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
15:41:22.103 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
15:41:22.113 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
15:41:22.113 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
15:41:22.114 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
------/127.0.0.1:59730------
15:41:55.957 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:41:55.958 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
15:41:55.958 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
15:41:55.958 [nioEventLoopGroup-2-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:41:55.966 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
15:41:55.966 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:41:55.967 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@7148612a
2023-01-03 15:41:55 [客户端] /127.0.0.1:59767 加入聊天
[客户] /127.0.0.1:59767 发送消息:我是59767
[客户] /127.0.0.1:59696 发送消息:你好,我是tom
我是6666
[自己]发送了消息:我是6666
2023-01-03 15:46:55 [客户端] /127.0.0.1:59696 离开聊天

4、客户端3日志

15:41:54.500 [main] DEBUG io.netty.util.internal.logging.InternalLoggerFactory - Using SLF4J as the default logging framework
15:41:54.507 [main] DEBUG io.netty.channel.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
15:41:54.530 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
15:41:54.530 [main] DEBUG io.netty.util.internal.InternalThreadLocalMap - -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
15:41:54.539 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
15:41:54.539 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
15:41:54.560 [main] DEBUG io.netty.util.internal.PlatformDependent - Platform: Windows
15:41:54.564 [main] DEBUG io.netty.util.internal.PlatformDependent0 - -Dio.netty.noUnsafe: false
15:41:54.564 [main] DEBUG io.netty.util.internal.PlatformDependent0 - Java version: 8
15:41:54.566 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
15:41:54.567 [main] DEBUG io.netty.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
15:41:54.568 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
15:41:54.569 [main] DEBUG io.netty.util.internal.PlatformDependent0 - direct buffer constructor: available
15:41:54.570 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
15:41:54.570 [main] DEBUG io.netty.util.internal.PlatformDependent0 - jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
15:41:54.570 [main] DEBUG io.netty.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
15:41:54.570 [main] DEBUG io.netty.util.internal.PlatformDependent - sun.misc.Unsafe: available
15:41:54.571 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.tmpdir: C:\Users\sjcui\AppData\Local\Temp (java.io.tmpdir)
15:41:54.571 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
15:41:54.574 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.maxDirectMemory: 3767533568 bytes
15:41:54.574 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.uninitializedArrayAllocationThreshold: -1
15:41:54.576 [main] DEBUG io.netty.util.internal.CleanerJava6 - java.nio.ByteBuffer.cleaner(): available
15:41:54.576 [main] DEBUG io.netty.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
15:41:54.590 [main] DEBUG io.netty.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
15:41:55.077 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.processId: 8304 (auto-detected)
15:41:55.080 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv4Stack: false
15:41:55.081 [main] DEBUG io.netty.util.NetUtil - -Djava.net.preferIPv6Addresses: false
15:41:55.486 [main] DEBUG io.netty.util.NetUtil - Loopback interface: lo (Software Loopback Interface 1, 127.0.0.1)
15:41:55.486 [main] DEBUG io.netty.util.NetUtil - Failed to get SOMAXCONN from sysctl and file \proc\sys\net\core\somaxconn. Default: 200
15:41:55.862 [main] DEBUG io.netty.channel.DefaultChannelId - -Dio.netty.machineId: 00:50:56:ff:fe:c0:00:01 (auto-detected)
15:41:55.876 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
15:41:55.876 [main] DEBUG io.netty.util.ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 16
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 16
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
15:41:55.904 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimIntervalMillis: 0
15:41:55.905 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
15:41:55.906 [main] DEBUG io.netty.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
15:41:55.916 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.allocator.type: pooled
15:41:55.916 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 0
15:41:55.916 [main] DEBUG io.netty.buffer.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 16384
------/127.0.0.1:59767------
我是59767
15:43:47.059 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 4096
15:43:47.059 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
15:43:47.059 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
15:43:47.059 [main] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
15:43:47.075 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkAccessible: true
15:43:47.075 [nioEventLoopGroup-2-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.checkBounds: true
15:43:47.077 [nioEventLoopGroup-2-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@48187557
[自己]发送了消息:我是59767
[客户] /127.0.0.1:59696 发送消息:你好,我是tom
[客户] /127.0.0.1:59730 发送消息:我是6666
2023-01-03 15:46:55 [客户端] /127.0.0.1:59696 离开聊天
2023-01-03 15:48:26 [客户端] /127.0.0.1:59730 离开聊天

Java基础之《netty(18)—群聊系统》相关推荐

  1. Netty解决TCP粘包/拆包导致的半包读写问题

    一.TCP粘包/拆包问题说明 TCP是个"流"协议,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包拆分,所以在业务上认为,一 ...

  2. Netty学习总结(5)——Netty之TCP粘包/拆包问题的解决之道

    无论是服务端还是客户端,读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制. TCP粘包/拆包 TCP是个"流"协议. 流:没有界限的一串数据.如同河里的流水,它们是连成 ...

  3. netty解决TCP粘包/拆包导致的半包读写问题的三种方案

    解决方案一:LineBasedFrameDecoder+StringDecoder来解决TCP的粘包/拆包问题 只需要在客户端和服务端加上45.46两行代码并且在发送消息的时候加上换行符即可解决TCP ...

  4. Java基础之《netty(28)—TCP粘包拆包原理》

    一.基本介绍 1.TCP是面向连接的,面向流的,提供高可靠性服务.收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方,使用了优化方法(Na ...

  5. Netty 之 TCP粘包拆包场景

    转自:http://blog.csdn.net/z69183787/article/details/52595980 TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输 ...

  6. Netty(二)——TCP粘包/拆包

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7814644.html 前面讲到:Netty(一)--Netty入门程序 主要内容: TCP粘包/拆包的基础知 ...

  7. java tcp怎么拆包_Java网络编程基础之TCP粘包拆包

    TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想象河里的流水,他们是连成一片的,其间并没有分界线.TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实 ...

  8. 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)

    一.粘包/拆包概念 TCP是一个"流"协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的 ...

  9. Netty详解(五):Netty TCP粘包 拆包

    1. 概述 无论是服务端还是客户端,我们读取或者发送消息的时候,都需要考虑TCP底层的粘包和拆包机制.下面我们来通过Netty来详解TCP底层的粘包和拆包机制. 2. TCP底层的粘包和拆包机制 TC ...

  10. 一起学Netty(六)之 TCP粘包拆包场景

    TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输的时候,在网络中的byte其实就像是河水,TCP就像一个搬运工,将这流水从一端转送到另一端,这时又分两种情况: 1)如 ...

最新文章

  1. Java格式化日期用斜杠_[java工具类01]__构建格式化输出日期和时间的工具类
  2. Bugzilla集成LDAP的方法
  3. ELF格式解析库之提取信息
  4. 将pcre、zlib等包编译进nginx里去(转)
  5. 模态对话框与非模态对话的几种销毁方法与区别
  6. win7下卸载linux系统(不用windows光盘)
  7. java服务器向客户端发消息_java一个简单的客户端向服务端发送消息
  8. bi power 两个日期挑较早的日期_功率 BI 中的时间智能:利用时间
  9. 【AI视野·今日CV 计算机视觉论文速览 第191期】Wed, 5 May 2021
  10. Beyond Compare 4
  11. Scala:未受重视却潜力巨大的Android编程语言
  12. oracle -3233,ORA-3233表空间相关问题处理
  13. 算法学习 - 拼接成最大的数字
  14. CrashLoopBackOff
  15. 【折半搜索-经典题目】中山纪念中学暑期游Day13——【GDOI2017模拟8.15】Buy
  16. 传感器检测系统及实训QY-812G
  17. Event Loop 原来是这么回事
  18. antd pro使用iconfont
  19. N卡多屏DP接口显示器不显示BIOS
  20. vue 解决ios15适配 input框出现两个放大镜的问题

热门文章

  1. 跟着Code走,详解Symbian OS API调用过程
  2. Atiitt 可视化 报表 图表之道 attilax著 Atiitt 可视化的艺术 attilax著 v2 s51.docx Atitit.可视化与报表原理与概论 1. 、什么是可视化(这一
  3. 第四周作业——统计/etc/init.d/functions文件中每个单词的出现次数,并排序(用grep和sed两种方法分别实现)
  4. android系统平台,Android系统平台 实用小软件推荐
  5. 松下S1H相机断电.MDT修复为MOV视频方法和格式编码信息
  6. 基于 CPU 实施高效且快速的医疗影像分析
  7. 12 -- OpenCV学习—边缘检测
  8. 关于python 如何实现数据内两两特征相乘
  9. 用AI说再见!“辣眼睛”的买家秀 2
  10. 易语言自绘系列教程(美易自绘)(第一部分)