Netty实现Socket

从Java1.4开始, Java引入了non-blocking IO,简称NIO。NIO与传统socket最大的不同就是引入了Channel和多路复用selector的概念。传统的socket是基于stream的,它是单向的,有InputStream表示read和OutputStream表示写。而Channel是双工的,既支持读也支持写,channel的读/写都是面向Buffer。 NIO中引入的多路复用Selector机制(如果是linux系统,则应用的epoll事件通知机制)可使一个线程同时监听多个Channel上发生的事件。 虽然Java NIO相比于以往确实是一个大的突破,但是如果要真正上手进行开发,且想要开发出好的一个服务端网络程序,那么你得要花费一点功夫了,毕竟Java NIO只是提供了一大堆的API而已,对于一般的软件开发人员来说只能呵呵了。因此,社区中就涌现了很多基于Java NIO的网络应用框架,其中以Apache的Mina,以及Netty最为出名。

一、Netty实现Socket

1、Netty服务端示例:

EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)  // (3)
.channel(NioServerSocketChannel.class) // (4)
.handler(new LoggingHandler()) // (5)
.childHandler(new ChannelInitializer<SocketChannel>() { // (6)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (7)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (8) // Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync(); // (9) // Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}

上面这段代码展示了服务端的一个基本步骤:

(1)、初始化用于Acceptor的主"线程池"以及用于I/O工作的从"线程池";

(2)、初始化ServerBootstrap实例, 此实例是netty服务端应用开发的入口;

(3)、通过ServerBootstrap的group方法,设置(1)中初始化的主从"线程池";

(4)、指定通道channel的类型,由于是服务端,故而是NioServerSocketChannel;

(5)、设置ServerSocketChannel的处理器(此处不详述,后面的系列会进行深入分析)

(6)、设置子通道也就是SocketChannel的处理器, 其内部是实际业务开发的"主战场"

(7)、配置ServerSocketChannel的选项

(8)、配置子通道也就是SocketChannel的选项

(9)、绑定并侦听某个端口

2、Netty客户示例:

public class TimeClient {
public static void main(String[] args) throws Exception {
String host = args[0];
int port = Integer.parseInt(args[1]);
EventLoopGroup workerGroup = new NioEventLoopGroup(); // (1) try {
Bootstrap b = new Bootstrap(); // (2)
b.group(workerGroup); // (3)
b.channel(NioSocketChannel.class); // (4)
b.option(ChannelOption.SO_KEEPALIVE, true); // (5)
b.handler(new ChannelInitializer<SocketChannel>() { // (6)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
}); // Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (7) // Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}

客户端的开发步骤和服务端都差不多:

(1)、初始化用于连接及I/O工作的"线程池";

(2)、初始化Bootstrap实例, 此实例是netty客户端应用开发的入口;

(3)、通过Bootstrap的group方法,设置(1)中初始化的"线程池";

(4)、指定通道channel的类型,由于是客户端,故而是NioSocketChannel;

(5)、设置SocketChannel的选项(此处不详述,后面的系列会进行深入分析);

(6)、设置SocketChannel的处理器, 其内部是实际业务开发的"主战场";

(7)、连接指定的服务地址;

二、Netty实现SSLSocket

netty创建服务端时,在初始化channl时,把handler加入ChannelPipeline时,在最开始那个handler设为SslHandler:

SSLContext sslContext = SslUtil.createSSLContext(type ,path ,password); ///SslUtil自定义类
SSLEngine sslEngine = sslContext.createSSLEngine(); sslEngine.setUseClientMode(false); /// 是否使用客户端模式 sslEngine.setNeedClientAuth(false); ////是否需要验证客户端
pipeline.addLast("ssl", new SslHandler(sslEngine));

SslUtil类:

private static volatile SSLContext sslContext = null;

public static SSLContext createSSLContext(String type ,String path ,String password) throws Exception {
  if(null == sslContext){
     synchronized (SslUtil.class) {
      if(null == sslContext){         KeyStore ks = KeyStore.getInstance(type); /// "JKS"        
        InputStream ksInputStream = new FileInputStream(path); /// 证书存放地址
       ks.load(ksInputStream, password.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, null);
      }
    }
  }
return sslContext;
}

参考博客:

[1]Netty4.x 源码实战系列(一): 深入理解ServerBootstrap 与 Bootstrap (1)

[2]Netty 实现SSL安全连接(wss://)

[3]Netty笔记之三:Netty实现Socket编程

[4]Netty框架学习之(一):Netty框架简介

[5]深入理解Netty框架

Netty实现Socket的更多相关文章

  1. netty 实现socket服务端编写

    import java.net.InetSocketAddress; import io.netty.bootstrap.ServerBootstrap; import io.netty.channe ...

  2. 基于netty的socket服务端触发了channelInactive方法,但实际连接没有断开的问题

    背景: 一个中小型H5游戏,后端使用基于 netty 的socket服务 服务端 分为 分发服务器 & 业务服务器,业务服务器可负载 用户客户端与分发服务器连接 分发服务器再作为客户端与每台业 ...

  3. SpringBoot整合Netty实现socket通讯简单demo

    依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifa ...

  4. java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

    之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...

  5. netty socket 客服端编程

    package com.ming.netty.nio; 2 3 import io.netty.bootstrap.Bootstrap; 4 import io.netty.channel.Chann ...

  6. Netty实现的一个异步Socket代码

    本人写的一个使用Netty实现的一个异步Socket代码 package test.core.nio; import com.google.common.util.concurrent.ThreadF ...

  7. day 4 Socket 和 NIO Netty

    Scoket通信--------这是一个例子,可以在这个例子的基础上进行相应的拓展,核心也是在多线程任务上进行修改 package cn.itcast.bigdata.socket; import j ...

  8. Socket通讯-Netty框架实现Java通讯

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

  9. netty同时实现http与socket

    (1)启动类 package test; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.EventLoopGro ...

随机推荐

  1. 2016西邮Linux兴趣小组大事记

    2016年还有半个小时就结束了,前面把自己9月做的规划拿出来完善了下,觉得真的是不容易的一年,所有的事情只有自己经历过才会有不一样的感受,世上无难事,只怕有心人. 这是我九月份制定的计划: 下面是20 ...

  2. ONVIF协议客户端

    前几天跟大家聊了一些关于ONVIF的一些基础知识,它的工作原理以及优势.今天安徽思蔷信息科技为带大家了解一下simpleonvif 百度云盘下载地址:链接:https://pan.baidu.com/ ...

  3. 攻防世界 WEB 高手进阶区 XCTF Web_python_template_injection Writeup

    攻防世界 WEB 高手进阶区 XCTF Web_python_template_injection Writeup 题目介绍 题目考点 SSTI模板注入漏洞 Writeup 知识补充 模板注入:模板引 ...

  4. robot_framewok自动化测试--(2)创建第一个项目

    创建第一个robot_framewok项目 通过 RIDE 去学习和使用 Robot Framework 框架,对于初学者来说大大的降低了学习难度.所以后面对 Robot Framework 框架都将 ...

  5. sklearn之转换器和估计器

    sklearn之转换器和估计器 转换器 估计器(sklearn机器学习算法的实现) 转换器 想一下之前做的特征工程的步骤? 实例化(实例化的是一个转换器类(Transformer)--特征工程的父类) ...

  6. git 回滚版本

    方法一.(回滚到原来的版本) 1.在gitlab上找到要恢复的版本号,如: bbdca96 2.在客户端执行如下命令(执行前,先将本地代码切换到对应分支): git reset --hard bbdc ...

  7. c#.net 实现短网址的简单方法

    短网址,现在很流行了,本文为大家介绍用c#.net实现短网址的方法,有兴趣的朋友,不妨参考下. 短网址,也被叫做网址缩短.网址压缩选装. 这里我们用一个例子来说明其原理吧,假如您带了一包东西去超市购物 ...

  8. 『学了就忘』Linux软件包管理 — 40、Linux系统软件包介绍

    目录 1.Linux系统软件包分类 2.源码包说明 3.二进制包说明 4.RPM包的优缺点 4.RPM包的两种安装方法 5.总结 1.Linux系统软件包分类 Linux系统下的软件包只有源码包和二进 ...

  9. 菜鸡的Java笔记 第三十六 - java 函数式编程

    StudyLambda    Lambda 指的是函数式编程,现在最为流行的编程模式为面向对象,很多的开发者并不认可面向对象,所以很多的开发者宁愿继续使用 C 语言进行开发,也不愿意使用java,c+ ...

  10. [bzoj1105]石头花园

    首先$C/2=x_{max}+y_{max}-x_{min}-y_{min}=max(x_{max},y_{max})-min(x_{min},y_{min})+min(x_{max},y_{max} ...