|
|
|
@ -6,15 +6,15 @@ package com.msb.socket;/**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
|
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
|
|
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
|
|
|
import io.netty.channel.ChannelInitializer;
|
|
|
|
|
import io.netty.channel.EventLoopGroup;
|
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
|
import io.netty.channel.*;
|
|
|
|
|
import io.netty.channel.group.ChannelGroup;
|
|
|
|
|
import io.netty.channel.group.DefaultChannelGroup;
|
|
|
|
|
import io.netty.channel.nio.NioEventLoopGroup;
|
|
|
|
|
import io.netty.channel.socket.SocketChannel;
|
|
|
|
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
|
|
|
import io.netty.util.concurrent.EventExecutor;
|
|
|
|
|
import io.netty.util.concurrent.EventExecutorGroup;
|
|
|
|
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -28,57 +28,76 @@ public class Server {
|
|
|
|
|
|
|
|
|
|
private int port;
|
|
|
|
|
|
|
|
|
|
public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
|
|
|
|
|
|
|
|
|
public Server(int port) {
|
|
|
|
|
this.port = port;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void serverStart() {
|
|
|
|
|
EventLoopGroup bootGroup = new NioEventLoopGroup(1);
|
|
|
|
|
EventLoopGroup workGroup = new NioEventLoopGroup(3);
|
|
|
|
|
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
|
|
|
|
EventLoopGroup workGroup = new NioEventLoopGroup(2);
|
|
|
|
|
ServerBootstrap bootstrap = new ServerBootstrap();
|
|
|
|
|
bootstrap.group(bootGroup, workGroup)
|
|
|
|
|
.channel(NioServerSocketChannel.class)
|
|
|
|
|
.childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
|
@Override
|
|
|
|
|
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
|
|
|
|
socketChannel.pipeline().addLast(new Handler());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
bootstrap.bind(this.port).sync();
|
|
|
|
|
ChannelFuture future = bootstrap.group(bossGroup, workGroup)
|
|
|
|
|
.channel(NioServerSocketChannel.class)
|
|
|
|
|
.childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
|
@Override
|
|
|
|
|
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
|
|
|
|
socketChannel.pipeline().addLast(new ServerChildHandler());
|
|
|
|
|
}
|
|
|
|
|
}).bind(this.port).sync(); //这个sync是什么阻塞。这个sync是看bind有没有连接成功,成功了才继续往下执行
|
|
|
|
|
|
|
|
|
|
future.channel().closeFuture().sync();
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
bootGroup.shutdownGracefully();
|
|
|
|
|
bossGroup.shutdownGracefully();
|
|
|
|
|
workGroup.shutdownGracefully();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
new Server(8888);
|
|
|
|
|
new Server(8888).serverStart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Handler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
class ServerChildHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
|
|
|
|
|
private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
|
|
|
|
// super.channelRead(ctx, msg);
|
|
|
|
|
channelGroup.forEach(channel -> {
|
|
|
|
|
/*channelGroup.forEach(channel -> {
|
|
|
|
|
if( ! channel.equals(ctx.channel())) {
|
|
|
|
|
channel.writeAndFlush(msg);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});*/
|
|
|
|
|
|
|
|
|
|
ByteBuf buf = (ByteBuf) msg;
|
|
|
|
|
byte[] bytes = new byte[buf.readableBytes()];
|
|
|
|
|
buf.getBytes(buf.readerIndex(), bytes);
|
|
|
|
|
String message = new String(bytes);
|
|
|
|
|
if("bye".equals(message)) {
|
|
|
|
|
Server.clients.remove(ctx.channel());
|
|
|
|
|
ctx.close();
|
|
|
|
|
} else {
|
|
|
|
|
Server.clients.writeAndFlush(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
|
|
|
|
Server.clients.add(ctx.channel());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
|
|
|
|
// super.exceptionCaught(ctx, cause);
|
|
|
|
|
cause.printStackTrace();
|
|
|
|
|
//移除出现异常的客户端channel,并关闭连接
|
|
|
|
|
Server.clients.remove(ctx.channel());
|
|
|
|
|
ctx.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|