zoukankan      html  css  js  c++  java
  • Socket通讯-Netty框架实现Java通讯

    Netty简介

    Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
    

    也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

    “快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。

    本文的目的

    使用Netty实现一个Socket通讯,包括客户端和服务端,通过服务端进行监听,客户端发送信息,服务端可进行接收,并进行返回数据,完成一个完整的通讯。
    

    工程结构

    这里写图片描述

    POM文件配置

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.taowd.socket</groupId>
        <artifactId>SocketDemo2</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.6.Final</version>
            </dependency>
        </dependencies>
    </project>

    服务端代码

    EchoServer.java

    package Server;
    

    import java.nio.charset.Charset;

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    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.bytes.ByteArrayEncoder;
    import io.netty.handler.codec.string.StringEncoder;

    public class EchoServer {
    private final int port;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">EchoServer</span><span class="hljs-params">(<span class="hljs-keyword">int</span> port)</span> </span>{
        <span class="hljs-keyword">this</span><span class="hljs-preprocessor">.port = port<span class="hljs-comment">;
    }
    
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">start</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception </span>{
        EventLoopGroup bossGroup = <span class="hljs-keyword">new</span> NioEventLoopGroup()<span class="hljs-comment">;
    
        EventLoopGroup group = <span class="hljs-keyword">new</span> NioEventLoopGroup()<span class="hljs-comment">;
        <span class="hljs-keyword">try</span> {
            ServerBootstrap sb = <span class="hljs-keyword">new</span> ServerBootstrap()<span class="hljs-comment">;
            sb<span class="hljs-preprocessor">.option(ChannelOption<span class="hljs-preprocessor">.SO_BACKLOG, <span class="hljs-number"><span class="hljs-number">1024</span>)<span class="hljs-comment">;
            sb<span class="hljs-preprocessor">.group(group, bossGroup) <span class="hljs-comment">// 绑定线程池</span>
                    <span class="hljs-preprocessor">.channel(NioServerSocketChannel<span class="hljs-preprocessor">.class) <span class="hljs-comment">// 指定使用的channel</span>
                    <span class="hljs-preprocessor">.localAddress(<span class="hljs-keyword">this</span><span class="hljs-preprocessor">.port)<span class="hljs-comment">// 绑定监听端口</span>
                    <span class="hljs-preprocessor">.childHandler(<span class="hljs-keyword">new</span> ChannelInitializer&lt;SocketChannel&gt;() { <span class="hljs-comment">// 绑定客户端连接时候触发操作</span>
    
                        <span class="hljs-meta">@Override</span>
                        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initChannel</span><span class="hljs-params">(SocketChannel ch)</span> <span class="hljs-keyword">throws</span> Exception </span>{
                            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(<span class="hljs-string"><span class="hljs-string">"报告"</span>)<span class="hljs-comment">;
                            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(<span class="hljs-string"><span class="hljs-string">"信息:有一客户端链接到本服务端"</span>)<span class="hljs-comment">;
                            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(<span class="hljs-string"><span class="hljs-string">"IP:"</span> + ch<span class="hljs-preprocessor">.localAddress()<span class="hljs-preprocessor">.getHostName())<span class="hljs-comment">;
                            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(<span class="hljs-string"><span class="hljs-string">"Port:"</span> + ch<span class="hljs-preprocessor">.localAddress()<span class="hljs-preprocessor">.getPort())<span class="hljs-comment">;
                            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(<span class="hljs-string"><span class="hljs-string">"报告完毕"</span>)<span class="hljs-comment">;
    
                            ch<span class="hljs-preprocessor">.pipeline()<span class="hljs-preprocessor">.addLast(<span class="hljs-keyword">new</span> StringEncoder(Charset<span class="hljs-preprocessor">.forName(<span class="hljs-string"><span class="hljs-string">"GBK"</span>)))<span class="hljs-comment">;
                            ch<span class="hljs-preprocessor">.pipeline()<span class="hljs-preprocessor">.addLast(<span class="hljs-keyword">new</span> EchoServerHandler())<span class="hljs-comment">; <span class="hljs-comment">// 客户端触发操作</span>
                            ch<span class="hljs-preprocessor">.pipeline()<span class="hljs-preprocessor">.addLast(<span class="hljs-keyword">new</span> ByteArrayEncoder())<span class="hljs-comment">;
                        }
                    })<span class="hljs-comment">;
            ChannelFuture cf = sb<span class="hljs-preprocessor">.bind()<span class="hljs-preprocessor">.sync()<span class="hljs-comment">; <span class="hljs-comment">// 服务器异步创建绑定</span>
            System<span class="hljs-preprocessor">.out<span class="hljs-preprocessor">.println(EchoServer<span class="hljs-preprocessor">.class + <span class="hljs-string"><span class="hljs-string">" 启动正在监听: "</span> + cf<span class="hljs-preprocessor">.channel()<span class="hljs-preprocessor">.localAddress())<span class="hljs-comment">;
            cf<span class="hljs-preprocessor">.channel()<span class="hljs-preprocessor">.closeFuture()<span class="hljs-preprocessor">.sync()<span class="hljs-comment">; <span class="hljs-comment">// 关闭服务器通道</span>
        } <span class="hljs-keyword">finally</span> {
            group<span class="hljs-preprocessor">.shutdownGracefully()<span class="hljs-preprocessor">.sync()<span class="hljs-comment">; <span class="hljs-comment">// 释放线程池资源</span>
            bossGroup<span class="hljs-preprocessor">.shutdownGracefully()<span class="hljs-preprocessor">.sync()<span class="hljs-comment">;
        }
    }
    
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    
        <span class="hljs-keyword">new</span> EchoServer(<span class="hljs-number"><span class="hljs-number">8888</span>)<span class="hljs-preprocessor">.start()<span class="hljs-comment">; <span class="hljs-comment">// 启动</span>
    }
    

    }

    EchoServerHandler.java

    package Server;
    

    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.text.SimpleDateFormat;
    import java.util.Date;

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;

    public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    <span class="hljs-comment"><span class="hljs-comment">/*
     * channelAction
     *
     * channel 通道 action 活跃的
     *
     * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     *
     */</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">channelActive</span><span class="hljs-params">(ChannelHandlerContext ctx)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        System.out.println(ctx.channel().localAddress().toString() + <span class="hljs-string"><span class="hljs-string">" 通道已激活!"</span>);
    }
    
    <span class="hljs-comment"><span class="hljs-comment">/*
     * channelInactive
     *
     * channel 通道 Inactive 不活跃的
     *
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     *
     */</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">channelInactive</span><span class="hljs-params">(ChannelHandlerContext ctx)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        System.out.println(ctx.channel().localAddress().toString() + <span class="hljs-string"><span class="hljs-string">" 通道不活跃!"</span>);
        <span class="hljs-comment"><span class="hljs-comment">// 关闭流</span>
    
    }
    
    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * 
     *</span><span class="hljs-javadoctag"><span class="hljs-comment"> <span class="hljs-doctag">@author</span> Taowd
     * TODO  此处用来处理收到的数据中含有中文的时  出现乱码的问题
     * 2017年8月31日 下午7:57:28
     *</span><span class="hljs-javadoctag"><span class="hljs-comment"> <span class="hljs-doctag">@param</span> buf
     *</span><span class="hljs-javadoctag"><span class="hljs-comment"> <span class="hljs-doctag">@return</span>
     */</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">private</span> String </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">getMessage</span><span class="hljs-params">(ByteBuf buf)</span> </span>{
        <span class="hljs-keyword"><span class="hljs-keyword">byte</span>[] con = <span class="hljs-keyword"><span class="hljs-keyword">new</span> <span class="hljs-keyword"><span class="hljs-keyword">byte</span>[buf.readableBytes()];
        buf.readBytes(con);
        <span class="hljs-keyword"><span class="hljs-keyword">try</span> {
            <span class="hljs-keyword"><span class="hljs-keyword">return</span> <span class="hljs-keyword"><span class="hljs-keyword">new</span> String(con, <span class="hljs-string"><span class="hljs-string">"UTF-8"</span>);
        } <span class="hljs-keyword"><span class="hljs-keyword">catch</span> (UnsupportedEncodingException e) {
            e.printStackTrace();
            <span class="hljs-keyword"><span class="hljs-keyword">return</span> <span class="hljs-keyword"><span class="hljs-keyword">null</span>;
        }
    }
    
    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * 功能:读取服务器发送过来的信息
     */</span>
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">channelRead</span><span class="hljs-params">(ChannelHandlerContext ctx, Object msg)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        <span class="hljs-comment"><span class="hljs-comment">// 第一种:接收字符串时的处理</span>
        ByteBuf buf = (ByteBuf) msg;
        String rev = getMessage(buf);
        System.out.println(<span class="hljs-string"><span class="hljs-string">"客户端收到服务器数据:"</span> + rev);
    
    }
    
    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * 功能:读取完毕客户端发送过来的数据之后的操作
     */</span>
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">channelReadComplete</span><span class="hljs-params">(ChannelHandlerContext ctx)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        System.out.println(<span class="hljs-string"><span class="hljs-string">"服务端接收数据完毕.."</span>);
        <span class="hljs-comment"><span class="hljs-comment">// 第一种方法:写一个空的buf,并刷新写出区域。完成后关闭sock channel连接。</span>
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        <span class="hljs-comment"><span class="hljs-comment">// ctx.flush();</span>
        <span class="hljs-comment"><span class="hljs-comment">// ctx.flush(); //</span>
        <span class="hljs-comment"><span class="hljs-comment">// 第二种方法:在client端关闭channel连接,这样的话,会触发两次channelReadComplete方法。</span>
        <span class="hljs-comment"><span class="hljs-comment">// ctx.flush().close().sync(); // 第三种:改成这种写法也可以,但是这中写法,没有第一种方法的好。</span>
    }
    
    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * 功能:服务端发生异常的操作
     */</span>
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">exceptionCaught</span><span class="hljs-params">(ChannelHandlerContext ctx, Throwable cause)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        ctx.close();
        System.out.println(<span class="hljs-string"><span class="hljs-string">"异常信息:
    "</span> + cause.getMessage());
    }
    

    }

    客户端代码

    EchoClient.java

    package Cilent;
    

    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    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.bytes.ByteArrayEncoder;
    import io.netty.handler.codec.string.StringEncoder;
    import io.netty.handler.stream.ChunkedWriteHandler;

    public class EchoClient {
    private final String host;
    private final int port;

    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">EchoClient</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword"><span class="hljs-keyword">this</span>(<span class="hljs-number"><span class="hljs-number">0</span>);
    }
    
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">EchoClient</span><span class="hljs-params">(</span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">int</span> port)</span> </span>{
        <span class="hljs-keyword"><span class="hljs-keyword">this</span>(<span class="hljs-string"><span class="hljs-string">"localhost"</span>, port);
    }
    
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">EchoClient</span><span class="hljs-params">(String host, </span></span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword">int</span> port)</span> </span>{
        <span class="hljs-keyword"><span class="hljs-keyword">this</span>.host = host;
        <span class="hljs-keyword"><span class="hljs-keyword">this</span>.port = port;
    }
    
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">start</span><span class="hljs-params">()</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        EventLoopGroup group = <span class="hljs-keyword"><span class="hljs-keyword">new</span> NioEventLoopGroup();
        <span class="hljs-keyword"><span class="hljs-keyword">try</span> {
            Bootstrap b = <span class="hljs-keyword"><span class="hljs-keyword">new</span> Bootstrap();
            b.group(group) <span class="hljs-comment"><span class="hljs-comment">// 注册线程池</span>
                    .channel(NioSocketChannel.class) <span class="hljs-comment"><span class="hljs-comment">// 使用NioSocketChannel来作为连接用的channel类</span>
                    .remoteAddress(<span class="hljs-keyword"><span class="hljs-keyword">new</span> InetSocketAddress(<span class="hljs-keyword"><span class="hljs-keyword">this</span>.host, <span class="hljs-keyword"><span class="hljs-keyword">this</span>.port)) <span class="hljs-comment"><span class="hljs-comment">// 绑定连接端口和host信息</span>
                    .handler(<span class="hljs-keyword"><span class="hljs-keyword">new</span> ChannelInitializer&lt;SocketChannel&gt;() { <span class="hljs-comment"><span class="hljs-comment">// 绑定连接初始化器</span>
                        <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
                        <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">protected</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">initChannel</span><span class="hljs-params">(SocketChannel ch)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
                            System.out.println(<span class="hljs-string"><span class="hljs-string">"正在连接中..."</span>);
                            ch.pipeline().addLast(<span class="hljs-keyword"><span class="hljs-keyword">new</span> StringEncoder(Charset.forName(<span class="hljs-string"><span class="hljs-string">"GBK"</span>)));
                            ch.pipeline().addLast(<span class="hljs-keyword"><span class="hljs-keyword">new</span> EchoClientHandler());
                            ch.pipeline().addLast(<span class="hljs-keyword"><span class="hljs-keyword">new</span> ByteArrayEncoder());
                            ch.pipeline().addLast(<span class="hljs-keyword"><span class="hljs-keyword">new</span> ChunkedWriteHandler());
    
                        }
                    });
            <span class="hljs-comment"><span class="hljs-comment">// System.out.println("服务端连接成功..");</span>
    
            ChannelFuture cf = b.connect().sync(); <span class="hljs-comment"><span class="hljs-comment">// 异步连接服务器</span>
            System.out.println(<span class="hljs-string"><span class="hljs-string">"服务端连接成功..."</span>); <span class="hljs-comment"><span class="hljs-comment">// 连接完成</span>
    
            cf.channel().closeFuture().sync(); <span class="hljs-comment"><span class="hljs-comment">// 异步等待关闭连接channel</span>
            System.out.println(<span class="hljs-string"><span class="hljs-string">"连接已关闭.."</span>); <span class="hljs-comment"><span class="hljs-comment">// 关闭完成</span>
    
        } <span class="hljs-keyword"><span class="hljs-keyword">finally</span> {
            group.shutdownGracefully().sync(); <span class="hljs-comment"><span class="hljs-comment">// 释放线程池资源</span>
        }
    }
    
    <span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">public</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">static</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">void</span> </span><span class="hljs-title"><span class="hljs-function"><span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span><span class="hljs-keyword"><span class="hljs-function"><span class="hljs-keyword">throws</span> Exception </span>{
        <span class="hljs-keyword"><span class="hljs-keyword">new</span> EchoClient(<span class="hljs-string"><span class="hljs-string">"127.0.0.1"</span>, <span class="hljs-number"><span class="hljs-number">8888</span>).start(); <span class="hljs-comment"><span class="hljs-comment">// 连接127.0.0.1/65535,并启动</span>
    
    }
    

    }

    EchoClientHandler.java

    package Cilent;
    

    import java.nio.charset.Charset;

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.ByteBufUtil;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.util.CharsetUtil;

    public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * 向服务端发送数据
     */</span>
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    public void channelActive(<span class="hljs-type">ChannelHandlerContext</span> ctx) <span class="hljs-keyword"><span class="hljs-keyword">throws</span> <span class="hljs-type">Exception</span> {
        <span class="hljs-type">System</span>.out.println(<span class="hljs-string"><span class="hljs-string">"客户端与服务端通道-开启:"</span> + ctx.channel().localAddress() + <span class="hljs-string"><span class="hljs-string">"channelActive"</span>);
    
        <span class="hljs-type">String</span> sendInfo = <span class="hljs-string"><span class="hljs-string">"Hello 这里是客户端  你好啊!"</span>;
        <span class="hljs-type">System</span>.out.println(<span class="hljs-string"><span class="hljs-string">"客户端准备发送的数据包:"</span> + sendInfo);
        ctx.writeAndFlush(<span class="hljs-type">Unpooled</span>.copiedBuffer(sendInfo, <span class="hljs-type">CharsetUtil</span>.<span class="hljs-type">UTF_8</span>)); <span class="hljs-comment"><span class="hljs-comment">// 必须有flush</span>
    
    }
    
    <span class="hljs-javadoc"><span class="hljs-comment">/**
     * channelInactive
     *
     * channel 通道 Inactive 不活跃的
     *
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     *
     */</span>
    public void channelInactive(<span class="hljs-type">ChannelHandlerContext</span> ctx) <span class="hljs-keyword"><span class="hljs-keyword">throws</span> <span class="hljs-type">Exception</span> {
        <span class="hljs-type">System</span>.out.println(<span class="hljs-string"><span class="hljs-string">"客户端与服务端通道-关闭:"</span> + ctx.channel().localAddress() + <span class="hljs-string"><span class="hljs-string">"channelInactive"</span>);
    }
    
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    <span class="hljs-keyword"><span class="hljs-keyword">protected</span> void channelRead0(<span class="hljs-type">ChannelHandlerContext</span> ctx, <span class="hljs-type">ByteBuf</span> msg) <span class="hljs-keyword"><span class="hljs-keyword">throws</span> <span class="hljs-type">Exception</span> {
        <span class="hljs-type">System</span>.out.println(<span class="hljs-string"><span class="hljs-string">"读取客户端通道信息.."</span>);
        <span class="hljs-type">ByteBuf</span> buf = msg.readBytes(msg.readableBytes());
        <span class="hljs-type">System</span>.out.println(
                <span class="hljs-string"><span class="hljs-string">"客户端接收到的服务端信息:"</span> + <span class="hljs-type">ByteBufUtil</span>.hexDump(buf) + <span class="hljs-string"><span class="hljs-string">"; 数据包为:"</span> + buf.toString(<span class="hljs-type">Charset</span>.forName(<span class="hljs-string"><span class="hljs-string">"utf-8"</span>)));
    }
    
    <span class="hljs-annotation"><span class="hljs-meta">@Override</span>
    public void exceptionCaught(<span class="hljs-type">ChannelHandlerContext</span> ctx, <span class="hljs-type">Throwable</span> cause) <span class="hljs-keyword"><span class="hljs-keyword">throws</span> <span class="hljs-type">Exception</span> {
        ctx.close();
        <span class="hljs-type">System</span>.out.println(<span class="hljs-string"><span class="hljs-string">"异常退出:"</span> + cause.getMessage());
    }
    

    }

    执行结果图

    客户端信息 
    服务端信息 原文地址:https://www.cnblogs.com/jtlgb/p/8757587.html

  • 相关阅读:
    SDN第三次上机作业
    团队作业——Beta冲刺
    SDN第二次上机作业
    在mpvue中使用map如何避坑
    仿一个好玩的滑动效果
    乡音
    mpvue支持小程序的分包加载
    台风🌀和口腔溃疡
    记一次cocos项目的加载速度优化
    如何用ajax下载文件
  • 原文地址:https://www.cnblogs.com/jpfss/p/11496902.html
Copyright © 2011-2022 走看看