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">"异常信息:\r\n"</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

posted @ 2019-09-10 12:51  星朝  阅读(1482)  评论(0编辑  收藏  举报