标签:stat 通道 encoder 方法 允许 boot str this 捆绑
public class Program { public static void main(String[] args) throws Exception { EchoServer echoServer = new EchoServer("127.0.0.1", 8888); // 启动 echoServer.start(); } } class EchoServer { private final int port; private final String ip; public EchoServer(String ip, int port) { this.ip = ip; this.port = port; } public void start() throws Exception { // 创建用于监听accept的线程池 EventLoopGroup bossGroup = new NioEventLoopGroup(); // 创建用于处理队列和数据的线程池 EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); // BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时 // ,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。 bootstrap.option(ChannelOption.SO_BACKLOG, 1024); // SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口, // 即使以前建立的将此端口用做他们的本地端口的连接仍存在。 // 这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错。 // SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例, // 只要每个实例捆绑一个不同的本地IP地址即可。对于TCP, // 我们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。 // SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上, // 只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器。 // SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个套接口上时, // 还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有, // 而且只对UDP套接口而言(TCP不支持多播) bootstrap.option(ChannelOption.SO_REUSEADDR, true); // Netty4使用对象池,重用缓冲区 bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); // 绑定线程池 bootstrap.group(group, bossGroup); // 指定使用的channel bootstrap.channel(NioServerSocketChannel.class); // 绑定监听端口 ; // 绑定客户端连接时候触发操作 bootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { System.out.println("报告"); System.out.println("信息:有一客户端链接到本服务端"); System.out.println("IP:" + ch.localAddress().getHostName()); System.out.println("Port:" + ch.localAddress().getPort()); System.out.println("报告完毕"); ch.pipeline().addLast(new StringEncoder(Charset.forName("GBK"))); System.out.println("客户端触发操作"); ch.pipeline().addLast(new EchoServerHandler()); // 客户端触发操作 ch.pipeline().addLast(new ByteArrayEncoder()); } }); ChannelFuture cf = bootstrap.bind(this.port).sync(); // 服务器异步创建绑定 System.out.println(EchoServer.class + " 启动正在监听: " + cf.channel().localAddress()); cf.channel().closeFuture().sync(); // 关闭服务器通道 } finally { // 释放线程池资源 group.shutdownGracefully().sync(); bossGroup.shutdownGracefully().sync(); } } } class EchoServerHandler extends ChannelInboundHandlerAdapter { /** * channelAction channel 通道 action 活跃的 * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据 */ public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().localAddress().toString() + " 通道已激活!"); } /** * channelInactive channel 通道 Inactive 不活跃的 * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据 */ public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().localAddress().toString() + " 通道不活跃!并且关闭。"); // 关闭流 ctx.close(); } /** * 功能:读取服务器发送过来的信息 */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 第一种:接收字符串时的处理 ByteBuf buf = (ByteBuf) msg; byte[] buffer = new byte[buf.readableBytes()]; buf.readBytes(buffer, 0, buffer.length); String rev = new String(buffer); System.out.println("客户端收到服务器数据:" + rev); ctx.writeAndFlush(rev); } /** * 功能:读取完毕客户端发送过来的数据之后的操作 */ @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("服务端接收数据完毕.."); // 第一种方法:写一个空的buf,并刷新写出区域。完成后关闭sock channel连接。 // ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); // ctx.flush(); // ctx.flush(); // // 第二种方法:在client端关闭channel连接,这样的话,会触发两次channelReadComplete方法。 // ctx.flush().close().sync(); // 第三种:改成这种写法也可以,但是这中写法,没有第一种方法的好。 } /** * 功能:服务端发生异常的操作 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println("异常信息:\r\n"); cause.printStackTrace(); } }
java 使用netty搭建tcp服务器(hello world)
标签:stat 通道 encoder 方法 允许 boot str this 捆绑
原文地址:https://www.cnblogs.com/jiecaoge/p/11131974.html