netty学习之一:第一个netty程序

news/2024/7/15 16:31:34 标签: netty, java

为什么80%的码农都做不了架构师?>>>   hot3.png

最近在学习netty,看了几天的博客之后,打算自己写一个练手的程序。

这个程序很简单:客户端发送一个ping,服务端会相应地回复一个pong,当监测到服务端失去连接后,即断开。

整个代码分为client与server两部分,结构如下:

引入netty包:

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.15.Final</version>
</dependency>

client端:

PingClient.java

java">package org.attempt.netty4.demo001.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
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.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class PingClient {

    /** 服务器IP地址 */
    private String host = "127.0.0.1";

    /** 服务器端口 */
    private int port = 8000;

    private EventLoopGroup group = null;
    private Bootstrap b = null;
    private Channel channel = null;

    public PingClient() throws Exception {
        group = new NioEventLoopGroup();
        b = new Bootstrap();
        b.group(group)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        channel.pipeline()
                                //字符串解码和编码
                                .addLast(new StringDecoder())
                                .addLast(new StringEncoder())
                                //客户端的逻辑
                                .addLast(new PingClientHandler());
                    }
                });
    }

    public Channel getChannel() throws Exception {
        if(null == channel || !channel.isActive()) {
            channel = b.connect(host, port).sync().channel();
        }
        return channel;
    }

    public static void main(String[] args) throws Exception {
        PingClient client = null;
        try {
            client = new PingClient();
            Channel channel = client.getChannel();

            while(true) {
                //输出channel的状态,对应于close()
                System.out.println(channel.isOpen());
                //判断连接状态
                if(channel.isActive()) {
                    channel.writeAndFlush("ping");
                } else {
                    System.out.println("失去连接,关闭客户端");
                    channel.close();
                    break;
                }
                Thread.sleep(5000);
            }
        } finally {
            if(null != client) {
                client.stop();
            }
        }
    }

    public void stop() {
        if(null != group) {
            //优雅退出,释放线程池资源
            group.shutdownGracefully();
        }
    }

}

PingClientHandler.java

java">package org.attempt.netty4.demo001.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class PingClientHandler extends SimpleChannelInboundHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("receive from server: " + msg.toString());
    }

}

server端: PongServer.java

java">package org.attempt.netty4.demo001.server;

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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class PongServer {

    public static void main(String[] args) throws Exception {
        int port = 8000;
        if (args != null && args.length > 0) {
            try {
                port = Integer.valueOf(args[0]);
            } catch (NumberFormatException e) {
                //采用默认值
            }
        }
        new PongServer().bind(port);
    }

    public void bind(int port) throws Exception {
        //配置服务端的NIO线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel channel) throws Exception {
                            channel.pipeline()
                            //字符串解码和编码
                            .addLast(new StringDecoder())
                            .addLast(new StringEncoder())
                            //服务器的逻辑
                            .addLast(new PongServerHandler());
                        }
                    });

            //绑定端口,同步等待成功
            ChannelFuture f = b.bind(port).sync();

            //等待服务器监听端口关闭
            f.channel().closeFuture().sync();
        } finally {
            //优雅退出,释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}

PongServerHandler.java

java">package org.attempt.netty4.demo001.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * @author admin
 * @date 2018-09-06 22:48
 */
public class PongServerHandler extends SimpleChannelInboundHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("receive from client: " + msg.toString());
        //返回客户端消息
        if(msg.toString().equals("ping")) {
            ctx.writeAndFlush("pong");
        } else {
            ctx.writeAndFlush("UNKONWN");
        }
    }

}

运行,先启动server端,再启动client端,结果如下:

  • server端:
receive from client: ping
receive from client: ping
receive from client: ping
receive from client: ping
receive from client: ping

Process finished with exit code -1
  • client端:
true
receive from server: pong
true
receive from server: pong
true
receive from server: pong
true
receive from server: pong
true
receive from server: pong
false
失去连接,关闭客户端

代码中的一些类及用法,后面再说。

转载于:https://my.oschina.net/funcy/blog/1976459


http://www.niftyadmin.cn/n/1475692.html

相关文章

BroadcastReceiver和Intetnt的理解 Day34

BroadcastReceiver和Intetnt的理解 Day34mobile4.0 短信监控问题堆栈 1. 下载开源项目View.网址自己fork一下 2. ContentProvider原理&#xff1b; 晚上完成 一些程序需要共享数据&#xff0c;每一个ContentProvider都有自己特定公共的URI 3. BroadcastReceiver机制的理解 广播…

c++ map key值不为基本类型的比较

STL中的map底层是用红黑树实现的&#xff0c;其泛型原型如下&#xff1a; template <class _Key, class _Tp, class _Compare, class _Alloc> class map {......} 其中_Key表示比较的键(key)&#xff0c;_Tp表示值(value)&#xff0c;_Compare表示比较方式&#xff0c;…

迟滞变化

上下限阈值&#xff0c;在很多情况下都存在&#xff0c;现在将从中单独的抽取出来。 一般存在如下的关系&#xff1a; 请问&#xff0c;这种东西有没有专门的学名&#xff1f; 简单的文字描述为&#xff1a; 当前处于Status_A下&#xff0c;当Value > Value_Max 时&#xff…

开源 | 深度有趣 - 人工智能实战项目合集

呕心沥血了大半年&#xff0c;《深度有趣》人工智能实战项目合集&#xff0c;终于完工上线了&#xff01; 《全栈》课程&#xff08;study.163.com/course/cour…&#xff09;获得好评之后&#xff0c;我一直打算再出一门课。 大方向和人工智能相关&#xff0c;但具体内容做什么…

使用 GNU autotools 改造一个软件项目

使用 GNU autotools 改造一个软件项目 本文不是一篇规范的教程&#xff0c;而是用一个软件项目作为例子&#xff0c;演示使用 GNU autotools 进行 软件管理的思路和过程 目 录 示例项目 软件布局 Makefile 分析 GNU 的软件风格 准备 autotools 改造文件布局 autoscan c…

Python面向对象的三大特征 --- 封装、继承、多态

一、封装 1&#xff09;封装&#xff1a;是面向对象的一大特点&#xff1b;将属性和方法封装在一个抽象类中。外界使用类创建对象&#xff0c;然后让对象调用内部方法。对象方法的细节都被封装在类的内部。 class Person(): def __init__(self,name,weight): # 初始化方法 s…

automake生成静态库和动态库

使用Automake 创建和使用静态库 1. 目录结构如下&#xff1a; example |——src 目录&#xff08;存放源代码文件&#xff09; |——hello.c |——lib 目录&#xff08;存放用来生成库的文件&#xff09; |——test.c 用来生成静态库libhello.a |——include …

转有关代码重构

转自&#xff1a;http://blog.csdn.net/weiky626/article/details/1602691 开发人员可能听到过"bad smell"这个词&#xff0c;这个词用在软件编码中是什么意思呢&#xff1f; 代码还有smell吗&#xff1f;当然没有&#xff0c;正如计算机病毒&#xff0c;bug等词一样…