package org.springblade.jfpt.nettyTcpServer;
|
|
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.Unpooled;
|
import io.netty.channel.*;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
import io.netty.util.ReferenceCountUtil;
|
|
|
public class TcpServer {
|
private int port;
|
private ServerSocketChannel serverSocketChannel;
|
|
public TcpServer(int port){
|
this.port = port;
|
bind();
|
}
|
|
private void bind() {
|
Thread thread = new Thread(new Runnable() {
|
@Override
|
public void run() {
|
//服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输
|
//连接处理group
|
EventLoopGroup boss = new NioEventLoopGroup();
|
//事件处理group
|
EventLoopGroup worker = new NioEventLoopGroup();
|
ServerBootstrap bootstrap = new ServerBootstrap();
|
// 绑定处理group
|
bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
|
//保持连接数
|
.option(ChannelOption.SO_BACKLOG, 30)
|
//设置缓冲区大小
|
.option(ChannelOption.SO_RCVBUF, 1024*1024)
|
.option(ChannelOption.SO_SNDBUF, 1024*1024)
|
//有数据立即发送
|
.option(ChannelOption.TCP_NODELAY, true)
|
//保持连接
|
.childOption(ChannelOption.SO_KEEPALIVE, true)
|
.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))
|
.childHandler(new NettyChannelHandler());
|
|
//绑定端口,同步等待成功
|
ChannelFuture future;
|
try {
|
future = bootstrap.bind(port).sync();
|
if (future.isSuccess()) {
|
serverSocketChannel = (ServerSocketChannel) future.channel();
|
System.out.println("服务端启动成功,端口:"+port);
|
} else {
|
System.out.println("服务端启动失败!");
|
}
|
|
//等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程
|
future.channel().closeFuture().sync();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
finally {
|
//优雅地退出,释放线程池资源
|
boss.shutdownGracefully();
|
worker.shutdownGracefully();
|
|
}
|
}
|
});
|
thread.start();
|
}
|
|
|
|
private class NettyChannelHandler extends ChannelInitializer<SocketChannel> {
|
|
@Override
|
protected void initChannel(SocketChannel socketChannel)
|
throws Exception {
|
ByteBuf delimiter = Unpooled.copiedBuffer("}".getBytes());
|
socketChannel.pipeline().addLast( new DelimiterBasedFrameDecoder(200000,delimiter));
|
socketChannel.pipeline().addLast(new TcpServerHandler());
|
}
|
}
|
|
}
|