实现一个基于nio的discard server

news2024/11/15 15:35:44

写在前面

源码 。
为了能够进一步的熟悉下nio相关的api操作,本文来实现一个基于nio的discard server。

discard server的意思是,server接收到来自client的一个消息之后,直接就将连接关闭,即discard。

1:正戏

1.1:server

package com.dahuyou.nio.discard.server.server;

import java.net.InetSocketAddress;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * nio discard server服务端
 */
public class NioDiscardServer {

    public static void main(String[] args) throws Exception {
        // 1:打开选择器
        Selector selector = Selector.open();
        // 2:获取通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 3:设置为非阻塞(阻塞了也就失去了nio的意义了!并且只有非阻塞才支持绑定事件)
        serverSocketChannel.configureBlocking(false);
        // 4:绑定链接
        serverSocketChannel.bind(new InetSocketAddress(18899));
        // 5:注册io事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("服务器启动成功");

        // 6:阻塞方式轮询感兴趣的通道事件(IO就绪)
        while (selector.select() > 0) {
            // 7:获取封装事件+通道的选择键的集合
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                // 8:获取某个选择键进行处理
                SelectionKey selectionKey = iterator.next();
                // 9:判断具体的事件,并进行处理
                if (selectionKey.isAcceptable()) {
                    System.out.println("新连接来了:" + selectionKey.channel());
                    // 10:就绪事件,获取客户端的链接(一个个来建立链接???可能不是个问题!!!不太明白这里为什么
                    // 这么写???)
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    // 11:设置为非阻塞
                    socketChannel.configureBlocking(false);
                    // 12:注册到选择器监听相关事件
//                    SelectionKey register = socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT);
                    socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT);
                }
                // 可写事件
                if (selectionKey.isWritable()) {
                    System.out.println("可写啦," + selectionKey.channel());
                }
                if (selectionKey.isConnectable()) {
                    System.out.println("连接成功啦," + selectionKey.channel());
                }
                if (selectionKey.isReadable()) {
                    System.out.println("数据可读啦," + selectionKey.channel());
                    // 13:获取通道,为读取数据做准备啦
                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                    // 14:读取数据啦
                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                    int length = 0;
                    while ((length = socketChannel.read(byteBuffer)) > 0) {
                        // 转成读模式
                        byteBuffer.flip();
                        System.out.println("读取到数据:" + new String(byteBuffer.array(), 0, length));
                        // 恢复成写模式(这里其实不用的,但当个好习惯吧!)
                        byteBuffer.clear();
                    }
                    // 读完消息了,就discard(discard server的体现指出)
                    socketChannel.close();
                }
                // 15:移出选择键,防止重复处理
                iterator.remove();
            }
        }
        System.out.println("discard 啦!!!!!!!!!!!!");
        // 关闭链接(这里应该是执行不到的,因为selector.select啦)
        serverSocketChannel.close();
    }

}

代码socketChannel.close();在read消息后,就discard啦!另外,关键步骤的代码看带标号的。

1.2:client

package com.dahuyou.nio.discard.server.client;

import io.netty.buffer.ByteBuf;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class NioDiscardClient {

    public static void main(String[] args) throws Exception {
        InetSocketAddress inetSocketAddress
                = new InetSocketAddress("127.0.0.1", 18899);
        // 1:获取通道
        SocketChannel socketChannel = SocketChannel.open(inetSocketAddress);
        // 2:切换成非阻塞
        socketChannel.configureBlocking(false);
        // 不断自旋,等待连接完成
        while (!socketChannel.finishConnect()) {}
        System.out.println("链接server成功");
        // 3:创建缓冲区,填充数据,并向通道写入数据
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put("hello discard server".getBytes());
        // 转成读模式,开始读数据写出去
        byteBuffer.flip();
        socketChannel.write(byteBuffer);
        System.out.println("向server写数据done");

        // 关了,释放资源,好习惯
        socketChannel.shutdownOutput();
        socketChannel.close();
    }
}

1.3:运行测试

在这里插入图片描述

写在后面

参考文章列表

使用NIO实现Discard服务器的实践案例 。

使用NIO实现Discard服务器的实践案例 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2159383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL深度探索:掌握触发器自动化与精细用户权限管理,提升数据库效能与安全

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言&#x…

gitlab集成CI/CD,shell方式部署

目录 1.首先安装好gitlab和gitlab-runner&#xff0c;这两个&#xff0c;看我以往的教程 2.注册新的 Runner 3. 步骤 3.1 Enter the GitLab instance URL (for example, https://gitlab.com/): 3.2 Enter the registration token: 3.3 Enter a description for the runner: 3…

【2024.09】关于 UMLS 在支持大型语言模型提出的诊断生成中的作用

生物医学信息学杂志 链接&#xff1a;https://www.sciencedirect.com/science/article/abs/pii/S1532046424001254?via%3Dihub On the role of the UMLS in supporting diagnosis generation proposed by Large Language Models Author links open overlay panelMajid Afsh…

线上搭子小程序:随时随地找搭子!

搭子作为当下流行的一种社交方式&#xff0c;受到了年轻人的讨论关注&#xff0c;不管做什么都可以找不同的“搭子”。追剧、考试、健身、减肥、旅游等都可以找到志趣相投的搭子&#xff0c;满足年轻人的社交需求。 在互联网的发展下&#xff0c;年轻人找搭子也逐渐倾向于线上…

ubuntu22 解决docker无法下载镜像问题

参考在 Ubuntu 中安装 Docker_ubuntu安装docker-CSDN博客 安装docker完成后&#xff0c;运行如下命令验证 Docker 服务是否在运行&#xff1a; systemctl status docker 运行&#xff08;sudo docker run hello-world&#xff09;例子报错&#xff1a; 问题&#xff1a;Docker…

ubuntu内网穿透后在公网使用ssh登录

需求&#xff1a; 我有一台内网可以通过ssh 22端口访问的设备操作系统是ubuntu server我还有1台拥有公网IP的服务器&#xff0c;IP地址是 6.66.666.6666我想随时从其他网段通过ssh访问我的ubuntu server设备 实现&#xff1a; 工具准备&#xff1a;frp 网址&#xff1a;https…

一看就会!PS2024下载安装教程详解

PS2024下载方法&#xff1a; PS2024安装教程&#xff1a; 1、右击【PS2024.zip】&#xff0c;选择【解压到PS2024】 2、右击【Set-up.exe】&#xff0c;选择【以管理员身份运行】 3、点击右下角灰色的小文件夹图标&#xff0c;选择【更改位置】 4、选择安装路径后&#xff0c;…

【每日刷题】Day130

【每日刷题】Day130 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; 2. 94. 二叉树的中序遍历 - 力扣…

注册安全分析报告:闪送

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

C#测试调用Ghostscript.NET浏览PDF文件

Ghostscript.NET是针对Ghostscript的C#封装库&#xff0c;支持解析PostScript语言、操作PDF文件等。使用Ghostscript.NET的GhostscriptViewer 模块可以以图片形式查看PDF文档。本文学习并测试调用Ghostscript.NET模块打开及浏览PDF文件的基本用法。   Ghostscript.NET目前主要…

.NET 6.0 WebAPI 使用JWT生成Token的验证授权

1.引入相关程序包JwtBearer注意版本: 2.配置文件appsettings.json写相关配置参数(也可不写&#xff0c;写在程序里面&#xff0c;数据库读取也是一样的) , //JWT加密"JWTToken": {"SecretKey": "jsaduwqe6asdjewejdue7dfmsdfu0sdfmwmsd8wfsd6",…

洛谷-P3916 图的遍历

题目描述 给出 N 个点&#xff0c;M 条边的有向图&#xff0c;对于每个点 v&#xff0c;求A(v) 表示从点 v 出发&#xff0c;能到达编号最大的点。 思路 既然是要找到最大的点&#xff0c;那么我从最大的点开始DFS是否可以&#xff1f; 于是可以反向建图&#xff0c;然后从最…

HTML图片标记(四)配图详解

目录 1.HTML图片的基础语法 2.设置图片大小 3.改变图片边距 4.图片对齐方式 1.HTML图片的基础语法 <img src"图片路径"> 2.设置图片大小 <img src"图片路径" width"" length""> 3.改变图片边距 <img src"…

Python 二次开发金橙子打印软件:开启高效打印新旅程

目录 一、准备工作&#xff1a;搭建系统环境 二、二次开发流程详解 结合一个实例来讲解如何进行二次开发。 三、Python 二次开发关键要素 &#xff08;一&#xff09;源码示例与解读 &#xff08;二&#xff09;二次开发文档指引 四、问题汇总与解决方案 &#xff08;一…

【HTML5】html5开篇基础(2)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

Spring Boot 学习之路 -- 配置项目

前言 最近因为业务需要&#xff0c;被拉去研究后端的项目&#xff0c;代码基于 Spring Boot&#xff0c;对我来说完全小白&#xff0c;需要重新学习研究…出于个人习惯&#xff0c;会以 Blog 文章的方式做一些记录&#xff0c;文章内容基本来源于「 Spring Boot 从入门到精通&…

【一起学NLP】Chapter2-学习神经网络

目录 学习神经网络损失函数Tip:One-hot向量导数与梯度Tip:严格地说链式法则计算图反向传播其他典型的运算结点乘法结点分支节点Repeat节点Sum节点MatMul节点 Tip:浅拷贝和深拷贝的差异梯度的推导和反向传播的实现Sigmoid层Affine层Softmax with Loss层 权重的更新——随机梯度下…

[PICO VR]Unity如何往PICO VR眼镜里写持久化数据txt/json文本

前言 最近在用PICO VR做用户实验&#xff0c;需要将用户实验的数据记录到PICO头盔的存储空间里&#xff0c;记录一下整个过程 流程 1.开启写入权限 首先开启写入权限&#xff1a;Unity->Edit->Player->安卓小机器人->Other Settings->Configuration->Wri…

大数据毕业设计选题推荐-网络电视剧收视率分析系统-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

数据库主备副本物理复制和逻辑复制对比

数据库主从节点的数据一致性是保证数据库高可用的基本要求&#xff0c;各个数据库在实现方式上也各有异同。而主备复制的方式无外乎两种&#xff1a;物理复制和逻辑复制&#xff0c;本文简要对比下两种方式的不同&#xff0c;并分析下国产数据库是如何实现的。 1、数据库复制基…