当前位置:   article > 正文

SpringBoot实现Socket客户端,Netty服务端实现Java通讯(附源码及注释详解)_java netty服务端与客户端相互通讯

java netty服务端与客户端相互通讯

SpringBoot实现Socket通讯:
使用Netty实现一个Socket通讯,包括客户端和服务端,通过服务端进行监听,客户端发送信息,服务端可进行接收,并进行返回数据,完成一个完整的通讯
客户端用的Socket编程,而服务端用到Netty框架实现。源码地址:

源码地址!!!!!!!!

而且启动初始化及调用的日志、注释写的很清楚,如下:

package com.xu.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * soket监听服务
 * 
 * @author xu
 */
public class NettyServer implements Runnable {

    /** 异常输出 */
    private static final Logger LOGGER = LoggerFactory.getLogger(NettyServer.class);

    /**
     * soket监听
     */
    public static void soketListener() {
    	LOGGER.info("================5.NettyServer开始启动========================");
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        int port = 58765;
        try {
        	LOGGER.info("================7.1 NettyServer 端口为:" + port + "========================");
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)  //绑定线程池
                .channel(NioServerSocketChannel.class)  // 指定使用的channel
                .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(64, 65535, 65535))
                .childHandler(new ChannelInitializer<SocketChannel>() { // 绑定客户端连接时候触发操作

                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    LOGGER.info("================7.2 报告,有个socket客户端链接到本服务器, IP为:" + ch.localAddress().getHostName() + ", Port为:" + ch.localAddress().getPort() + "========================");
                    ch.pipeline().addLast(new ServerHandler()); // 客户端触发操作
                }
            });
            LOGGER.info("================8.NettyServer 启动中.....========================");
            ChannelFuture channelFuture = bootstrap.bind(port).sync(); // 服务器异步创建绑定
            LOGGER.info("================9.NettyServer 启动完毕!!========================");
            channelFuture.channel().closeFuture().sync(); // 关闭服务器通道
            LOGGER.info("================41.NettyServer 关闭服务器通道!!========================");
        } catch (Exception e) {
        	LOGGER.error("================4.1 NettyServer 端口为:" + port + " 启动出现异常, 异常内容为:" + e.getMessage() + "========================");
        } finally {
        	LOGGER.error("================4.2 NettyServer 服务关闭========================");
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    /**
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        LOGGER.info("================4.多线程启动Netty Server========================");
        NettyServer.soketListener();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

这里就不再赘述!

下面写一下理论性的东西:

Netty很强大: 阿里的Dubbo的底层就是用的Netty

先从Socket讲起:

1. Socket 机制

Socket,又称为套接字,用于描述 IP 地址和端口。应用程序通常通过 socket向网络发出请求或者应答网络请求。Socket 就是为网络编程提供的一种机制:
通信两端都有 socket;
网络通信其实就是 socket 之间的通信;
数据在两个 socket 之间通过 IO 传输。
网络编程也称作为 Socket 编程,套接字编程。
Socket 通信是 Client/Server 模型

而网络通信的本质是网络间的数据 IO,这又牵扯出了 BIO 和 NIO这两个通讯模型:

2. IO通讯模型

只要有 IO,就会有阻塞或非阻塞的问题,无论这个 IO 是网络的,还是硬盘的。原因在于程序是运行在系统之上的,任何形式的IO 操作发起都需要系统内核的支持。

在这里插入图片描述

2.1 BIO(阻塞模式)

BIO 即 blocking IO,是一种阻塞式的 IO。
jdk1.4 版本之前 Socket 即 BIO 模式。
BIO 的问题在于 accept()、read()的操作点都是被阻塞的。
服务器线程发起一个 accept 动作,询问操作系统是否有新的 socket 信息从端口 X 发送过来。注意,是询问操作系统。如果操作系统没有发现有 socket 从指定的端口X 来,那么操作系统就会等待。这样 serverSocket.accept()方法就会一直等待。这就是为什么 accept()方法为什么会阻塞。
如果想让 BIO 同时处理多个客户端请求,就必须使用多线程,即每次 accept阻塞等待来自客户端请求,一旦收到连接请求就建立通信,同时开启一个新的线程来处理这个套接字的数据读写请求,然后立刻又继续 accept 等待其他客户端连接请求,即为每一个客户端连接请求都创建一个线程来单独处理。
在这里插入图片描述

2.2 NIO(非阻塞模式)

NIO 即 non-blocking IO,是一种非阻塞式的 IO。jdk1.4 之后提供。
NIO 三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)。 Buffer:容器对象,包含一些要写入或者读出的数据。在 NIO 库,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。任何时候访问 NIO 中的数据,都是通过缓冲区进行操作。
Channel:通道对象,对数据的读取和写入要通过 Channel,它就像水管一样。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。 Channel不会直接处理字节数据,而是通过 Buffer 对象来处理数据。
Selector:多路复用器,选择器。提供选择已经就绪的任务的能力。Selector会不断轮询注册在其上的 Channel,如果某个 Channel 上面发生读或者写事件,这个Channel 就处于就绪状态,会被 Selector 轮询出来,进行后续的 I/O 操作。这样服务器只需要一两个线程就可以进行多客户端通信。

在这里插入图片描述
在这里插入图片描述

而Netty就是使用的NIO,这也是Netty框架高性能的原因!!

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

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

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

Socket的客户端也可以由Netty实现,但是使用Socket直接实现客户端,而服务端由Netty实现,这样可以更好的理解Netty!

完!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/973862
推荐阅读
  

闽ICP备14008679号