Java网络编程之NIO服务端

Java网络编程之NIO服务端通过NIO实现的网络服务端代码一直比较复杂,这里简单的给大家梳理一下代码结构,希望能给大家带来一点帮助。package com.crazy.fa

大家好,欢迎来到IT知识分享网。Java网络编程之NIO服务端"

通过NIO实现的网络服务端代码一直比较复杂,这里简单的给大家梳理一下代码结构,希望能给大家带来一点帮助。

package com.crazy.fan.nettydemo.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 服务端
 */
public class NioServer {

    private static final ThreadPoolExecutor executors = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors()*2, 5, TimeUnit.MINUTES, new LinkedBlockingDeque<>(100));

    public static void main(String[] args) throws Exception{
        //创建长度为5的数组,声明5个端口
        int[] ports = new int[5];
        ports[0] = 8080;
        ports[1] = 8081;
        ports[2] = 8082;
        ports[3] = 8083;
        ports[4] = 8084;

        //创建一个选择器
        Selector selector = Selector.open();

        for (int i = 0; i < ports.length; i++) {
            //Opens a server-socket channel.
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            //设置通道为非阻塞模式
            serverSocketChannel.configureBlocking(false);
            //服务端套接字绑定指定的端口
            serverSocketChannel.bind(new InetSocketAddress(ports[i]));
            //将通道注册进选择器,并监听可连接的事件
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("监听端口: " + ports[i]);
        }

        while (true) {
            //监听事件发生(线程阻塞,有新的事件,线程才会继续向下执行)
            selector.select();
            //获取事件集合(如果有新的事件发生,则会放到这个集合里)
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                //将当前selectionKey从集合里移除
                iterator.remove();
                if (selectionKey.isAcceptable()) {//可连接事件
                    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    socketChannel.configureBlocking(false);
                    socketChannel.register(selector, SelectionKey.OP_READ);
                    System.out.println("获得客户端连接: " + socketChannel);
                } else if (selectionKey.isReadable()) {//可读事件
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(16);
                    try {
                        int read = socketChannel.read(buffer);
                        buffer.flip();
                        if (read > 0) {
                            //处理相关业务
                            executors.execute(new HandleTask(selectionKey, buffer));
                        } else if (read == -1) { //客户端主动断开连接
                            selectionKey.cancel();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        selectionKey.cancel();
                    }
                }
            }
        }
    }
    
}

/**
 * 任务处理类
 */
class HandleTask implements Runnable{

    private SelectionKey selectionKey;
    private ByteBuffer buffer;

    public HandleTask(SelectionKey selectionKey, ByteBuffer buffer) {
        this.selectionKey = selectionKey;
        this.buffer = buffer;
    }

    @Override
    public void run() {
        System.out.println("Threaname: " + Thread.currentThread().getName() + "接收到的数据: " + String.valueOf(Charset.defaultCharset().decode(buffer)));
    }
}

代码正常启动结果:

监听端口: 8080
监听端口: 8081
监听端口: 8082
监听端口: 8083
监听端口: 8084

谢谢大家耐心收看,喜欢的话,点个赞吧!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/65337.html

(0)
上一篇 2024-05-27 12:45
下一篇 2024-05-31 08:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信