首页 > 其他分享 >nio管道junit

nio管道junit

时间:2023-09-18 18:03:49浏览次数:39  
标签:java nio SocketChannel 管道 ByteBuffer import buf junit

一,nio中的网络io(nio的非阻塞式网络通信)

1,使用nio完成网络通信的3要素

-通道(Channel): 负责链接

SelectableChannel

SocketChannel

ServerSocketChannel

DatagramChannel

Pipe.SinkChannel Pipe.SourceChannel

-缓冲区(Buffer):负责数据存取

-选择器(Selector): 负责监控SelectableChannel状态

SelectableChannel对象的多路复用器 。

package com.momo.demo;

import org.junit.Test;

import java.io.IOException;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.UnknownHostException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

public class Demo1 {

@Test

public void server() throws IOException {

//获取通道

ServerSocketChannel sschannel = ServerSocketChannel.open();

//绑定端口

sschannel.bind(new InetSocketAddress(12345));

FileChannel outchannel = FileChannel.open(Paths.get("222.jpg"),StandardOpenOption.WRITE,StandardOpenOption.CREATE); //获取客户端链接 SocketChannel schannel = sschannel.accept(); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //接收数据,保存 while (schannel.read(buf)!=-1){ buf.flip(); outchannel.write(buf); buf.clear(); } } @Test //客户端 public void client() throws IOException { //获取通道 SocketChannel schannel = SocketChannel.open(new InetSocketAddress(InetAddress.getLocalHost(), 12345)); FileChannel inchannel = FileChannel.open(Paths.get("111.jpg"), StandardOpenOption.READ); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //读取本地文件,发送到服务端 while (inchannel.read(buf)!=-1){ buf.flip(); schannel.write(buf); buf.clear(); } //释放资源 inchannel.close(); schannel.close(); }

}

package com.momo.demo;

import org.junit.Test;

import java.io.IOException;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.UnknownHostException;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

//客户端发送数据,服务端反馈数据

public class Demo2 {

@Test

public void server() throws IOException {

//获取通道

ServerSocketChannel sschannel = ServerSocketChannel.open();

//绑定端口

sschannel.bind(new InetSocketAddress(12345));

FileChannel outchannel = FileChannel.open(Paths.get("222.jpg"),StandardOpenOption.WRITE,StandardOpenOption.CREATE); //获取客户端链接 SocketChannel schannel = sschannel.accept(); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //接收数据,保存 while (schannel.read(buf)!=-1){ buf.flip(); outchannel.write(buf); buf.clear(); } //给客户端反馈信息 buf.put("我收到了".getBytes()); buf.flip(); schannel.write(buf); schannel.close(); outchannel.close(); sschannel.close(); } @Test //客户端 public void client() throws IOException { //获取通道 SocketChannel schannel = SocketChannel.open(new InetSocketAddress(InetAddress.getLocalHost(), 12345)); FileChannel inchannel = FileChannel.open(Paths.get("111.jpg"), StandardOpenOption.READ); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //读取本地文件,发送到服务端 while (inchannel.read(buf)!=-1){ buf.flip(); schannel.write(buf); buf.clear(); } schannel.shutdownOutput(); //接收服务端额反馈信息 int len = 0; while ((len=schannel.read(buf))!=-1){ buf.flip(); System.out.println(new String(buf.array(),0,len)); buf.clear(); } //释放资源 inchannel.close(); schannel.close(); }

}

2,选择器

-如何获取选择器?

Selector.open() 方法获取

-如何把通道注册到选择器上?

使用通道的register(Selector s,int key) 方法

当调用这个方法的时候,要把通道注册到选择器上,需要指定

需要监测的事件,通过第二个参数来传递。

事件的类型,java给我们封装到了SelectionKey 中,用几个常量表示的。

如果需要监听多个事件,可以使用| 隔开

-你要让监听器监听什么事件?

java都已经给我们封装好了,在SelectionKey中。

-SelectionKey:表示SelectableChannel 和 Selector 之间的关系。

每次给选择器中注册通道的时候要选择一个事件(选择键)

static int OP_ACCEPT

就绪事件

static int OP_CONNECT

链接事件

static int OP_READ

可读

static int OP_WRITE

可写

int interestOps()

获取感兴趣的事件集合

int readyOps()

获取通道中已经准备就绪的状态集合

SelectableChannel channel()

获取注册通道

boolean isAcceptable()

测试此密钥的通道是否已准备好接受新的套接字连接。

boolean isConnectable()

测试此密钥的通道是否已完成或未完成其套接字连接操作。

boolean isReadable()

测试此密钥的频道是否可以阅读。

boolean isWritable()

测试此密钥的通道是否准备好进行写入。


package com.momo.demo;

import org.junit.Test;

import java.io.IOException;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.ServerSocket;

import java.net.UnknownHostException;

import java.nio.ByteBuffer;

import java.nio.channels.*;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

import java.util.Date;

import java.util.Iterator;

import java.util.Set;

//非阻塞式

public class Demo3 {

@Test

public void server() throws IOException {

//获取通道

ServerSocketChannel ssChannel = ServerSocketChannel.open();

//切换非阻塞模式

ssChannel.configureBlocking(false);

//绑定端口

ssChannel.bind(new InetSocketAddress(12345));

//获取选择器

Selector selector = Selector.open();

//使用选择器监听状态,把通道注册到监听器中,指定需要监听的状态(事件)

ssChannel.register(selector, SelectionKey.OP_ACCEPT);

//循环获取选择器上已经准备就绪的事件

while (selector.select()>0){

//获取当前在选择器中已经准备就绪的事件

//Set keys = selector.selectedKeys();

Iterator it = selector.selectedKeys().iterator();

// for (SelectionKey key : keys) {

while (it.hasNext()){

SelectionKey key = it.next();

//判断是否有准备就绪的事件

if(key.isAcceptable()){

//如果准备就绪,获取客户端链接

SocketChannel sChannel = ssChannel.accept();

//切换非阻塞模式

sChannel.configureBlocking(false);

//把通道注册到选择器上

sChannel.register(selector,SelectionKey.OP_READ);

}else if(key.isReadable()){

//获取可读通道

SocketChannel sChannel = (SocketChannel)key.channel();

//读取数据

ByteBuffer buf = ByteBuffer.allocate(1024);

int len = 0;

while ((len=sChannel.read(buf))!=-1){

buf.flip();

System.out.println(new String(buf.array(),0,len));

buf.clear();

}

}

//移除选择键(取消处理过的事件)

it.remove();

}

}

}

@Test //客户端 public void client() throws IOException { //获取通道 SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 12345)); //调用方法切换到非阻塞模式 sChannel.configureBlocking(false); //创建缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //发送数据 buf.put((new Date()+":你好").getBytes()); buf.flip(); sChannel.write(buf); buf.clear(); //释放资源 sChannel.close(); }

}

3,常用的类和方法 -SocketChannel static SocketChannel open(SocketAddress remote) 打开套接字通道并将其连接到远程地址。 SocketChannel shutdownInput() 关闭连接进行阅读,不关闭频道。 SocketChannel shutdownOutput() 关闭连接以进行写入,而不关闭通道。 SelectionKey register(Selector sel, int ops) SelectableChannel configureBlocking(boolean block) -ServerSocketChannel ServerSocketChannel open() ServerSocketChannel bind(SocketAddress local) SocketChannel accept() SelectableChannel configureBlocking(boolean block) SelectionKey register(Selector sel, int ops) -Selector static Selector open() 打开选择器。 int select() 选择一组其相应通道准备好进行I / O操作的键。 Set selectedKeys() 返回此选择器的选择键集。

package com.momo.demo;

import java.io.IOException;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SocketChannel;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Scanner;

public class Client {

public static void main(String[] args) throws IOException {

SocketChannel sChannel = SocketChannel.open(new InetSocketAddress(InetAddress.getLocalHost(), 6666));

sChannel.configureBlocking(false);

ByteBuffer buf = ByteBuffer.allocate(1024); Scanner sc = new Scanner(System.in); System.out.println("请输入:"); while (sc.hasNext()){ String str = sc.next(); buf.put((new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())+":"+str).getBytes()); buf.flip(); sChannel.write(buf); buf.clear(); } sChannel.close(); }

}

package com.momo.demo;

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.util.Iterator;

public class Server {

public static void main(String[] args) throws IOException {

ServerSocketChannel ssChannel = ServerSocketChannel.open();

ssChannel.configureBlocking(false);

ssChannel.bind(new InetSocketAddress(6666));

Selector selector = Selector.open(); ssChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select()>0){ Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()){ SelectionKey sk = it.next(); if(sk.isAcceptable()){ SocketChannel sChannel = ssChannel.accept(); sChannel.configureBlocking(false); sChannel.register(selector,SelectionKey.OP_READ); }else if(sk.isReadable()){ SocketChannel sChannel = (SocketChannel)sk.channel(); ByteBuffer buf = ByteBuffer.allocate(1024); int len = 0; while ((len=sChannel.read(buf))>0){ buf.flip(); System.out.println(new String(buf.array(),0,len)); buf.clear(); } } it.remove(); } } }

}

二,DatagramChannel

1,java nio包中DatagramChannel 是一个能收发upd包的通道

2,步骤

-打开DatagramChannel

-接收或者发送数据

package com.momo.demo;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.DatagramChannel;

import java.util.Scanner;

public class Send {

public static void main(String[] args) throws IOException {

DatagramChannel dc = DatagramChannel.open();

dc.configureBlocking(false);

ByteBuffer buf = ByteBuffer.allocate(1024);

Scanner sc = new Scanner(System.in);

while (sc.hasNext()){

String str = sc.next();

buf.put(str.getBytes());

buf.flip();

dc.send(buf,new InetSocketAddress("127.0.0.1",8888));

buf.clear();

}

dc.close();

}

}

package com.momo.demo;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.DatagramChannel;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.util.Iterator;

public class Receive {

public static void main(String[] args) throws IOException {

DatagramChannel dc = DatagramChannel.open();

dc.configureBlocking(false);

dc.bind(new InetSocketAddress(8888));

Selector selector = Selector.open(); dc.register(selector, SelectionKey.OP_READ); while (selector.select()>0){ Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()){ SelectionKey sk = it.next(); if(sk.isReadable()){ ByteBuffer buf = ByteBuffer.allocate(1024); dc.receive(buf); buf.flip(); System.out.println(new String(buf.array(),0,buf.limit())); buf.clear(); } it.remove(); } } }

}

三,管道(Pipe)

1,java nio 管道 是2个线程之间的单向数据链接

-Pipe 有一个source 通道 和一个sink 通道。

数据写到sink通道,从source读取

package com.momo.demo;

import org.junit.Test;

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.Pipe;

public class Demo6 {

@Test

public void test1() throws IOException {

//获取管道

Pipe pipe = Pipe.open();

//写数据

Pipe.SinkChannel sink = pipe.sink();

ByteBuffer buf = ByteBuffer.allocate(1024); buf.put("你好。小日子过的不错的人。".getBytes()); buf.flip(); sink.write(buf); //读取数据 Pipe.SourceChannel source = pipe.source(); buf.flip(); int len = source.read(buf); System.out.println(new String(buf.array(),0,len)); source.close(); sink.close(); }

}

四,juint单元测试

1,测试?

2,分类:

-黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。

-白盒测试:需要写代码的。关注程序具体的执行流程。

3,juint单元测试好处

-可以书写一系列的测试方法,对项目所有的接口或者方法进行单元测试。

-启动后,自动化测试,并判断执行结果, 不需要人为的干预。

-只需要查看最后结果,就知道整个项目的方法接口是否通畅。

-每个单元测试用例相对独立,由Junit 启动,自动调用。不需要添加额外的调用语句。

-添加,删除,屏蔽测试方法,不影响其他的测试方法。 开源框架都对JUnit 有相应的支持。

4,使用

-有一个MyMath类,里面有很多方法要进行测试

sum()

-步骤:

导入juint的jar包

编写一个测试类,测试类放在测试包 com.momo.test TestMyMath

定义测试方法 加入@Test注解 可以独立运行

testSum()

返回值void

参数空

判断结果:一般使用断言,红色表示失败,绿色表示成功。

package com.momo.util;

public class MyMath {

public int sum(int a,int b){

return a+b;

}

}

package com.momo.test;

import com.momo.util.MyMath;

import org.junit.Assert;

import org.junit.Test;

public class TestMyMath {

@Test

public void testSum(){

MyMath mm = new MyMath();

int sum = mm.sum(2, 3);

// System.out.println(sum);

//断言 我认为结果应该是什么

Assert.assertEquals(5,sum);

//Assert.assertEquals(4,sum);

}

/* @Test

public void testAvg(){

}*/

}

5,需要知道的注解

-@Test 测试方法上加

-@Before 在所有测试方法执行前,会自动执行

-@After 在所有测试方法执行完成后,会自动执行

package com.momo.test;

import com.momo.util.MyMath;

import org.junit.After;

import org.junit.Assert;

import org.junit.Before;

import org.junit.Test;

public class TestMyMath {

//在执行测试方法之前需要完成的一些初始化操作

//在所有测试方法执行前,会自动执行

@Before

public void init(){

System.out.println("创建依赖对象,完成一些初始化操作");

}

@Test

public void testSum(){

// System.out.println("创建依赖对象,完成一些初始化操作");

System.out.println("测试代码。。。");

MyMath mm = new MyMath();

int sum = mm.sum(2, 3);

// System.out.println(sum);

//断言 我认为结果应该是什么

Assert.assertEquals(5,sum);

//Assert.assertEquals(4,sum);

// System.out.println("释放依赖对象");

}

//在所有测试方法执行完成后,会自动执行

@After

public void close(){

System.out.println("释放依赖对象");

}

/* @Test public void testAvg(){ System.out.println("创建依赖对象,完成一些初始化操作"); 。。。。 System.out.println("释放依赖对象"); }*/ }

标签:java,nio,SocketChannel,管道,ByteBuffer,import,buf,junit
From: https://blog.51cto.com/u_16230968/7513807

相关文章

  • MinIO分布式部署
    目录先决条件网络和防火墙网络防火墙负载均衡顺序的主机名驱动器要求XFS格式性能最优最小IO顺序的驱动器名任意迁移时间同步考虑相同的硬软件环境存储容量规划推荐的操作系统预先存在的数据部署分布式MinIO在每一个节点上安装MinIO创建服务文件minio.service创建环境文件添加TLS/S......
  • NIO
    http://www.importnew.com/19816.htmlhttp://baike.baidu.com/link?url=ltnOyvylaoSeR0ZILehHzmyBaeOoz7MYfR3Aw1HAtJTc22TgJzHDZcCruXSkOsHvy42VorsitmQXlprGw8a0e7ywx4xN8qvLgcoPnv5WO-8_d277x1VY4qbVcY1koarabyxRCioJ3eUwUo4SepxXu_......
  • linux-管道符、重定向
    1、管道符   命令1|命令2   命令1的正确输出作为命令2的操作对象   如:查看xx.txt文件并且查找123字符      catxx.txt|grep"123"; 2、重定向     ......
  • nio---io区别 20230403
    文件的抽象化表示,字节流以及字符流的文件操作等属于传统IO的相关内容,我们已经在前面的文章进行了较为深刻的学习了。但是传统的IO流还是有很多缺陷的,尤其它的阻塞性加上磁盘读写本来就慢,会导致CPU使用效率大大降低。所以,jdk1.4发布了NIO包,NIO的文件读写设计颠覆了传统I......
  • Junit
    单元测试就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试。Junit的简单使用为需要测试的业务类,定义对应的测试类为每个业务方法,编写对应的测试方法(必须:公共public、无参、无返回值void)测试方法名推荐格式:test待测试方法名【首字母改为大写】测试方法上必......
  • P3933 Chtholly Nota Seniorious
    原题是一个完全不困难的题,但里面一个性质没有想到QwQ性质:最大值一定在两个部分之一(显然)于是我们二分答案后,\(O(n^2)\)的找到从左下角开始包含最大值且极差\(\leqx\)的所能覆盖的最大区域,然后判断另一个区域极差是否\(\leqx\)即可不一定从左下角开始?旋转\(4\)次做\(4\)次即......
  • Spring Boot + minio 实现高性能存储服务,So Easy~!
    什么是minio引用官网:MinIO是根据GNUAffero通用公共许可证v3.0发布的高性能对象存储。它与AmazonS3云存储服务兼容。使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构。官网地址:https://min.io/文档地址:https://docs.min.io/一.使用docker搭......
  • 使用 Sealos 一键部署高可用 MinIO,开启对象存储之旅
    大家好!今天这篇文章主要向大家介绍如何通过Sealos一键部署高可用MinIO集群。MinIO对象存储是什么?对象是二进制数据,例如图像、音频文件、电子表格甚至二进制可执行代码。对象的大小可以从几B到几TB不等。像MinIO这样的对象存储平台提供了专用工具和功能,使用标准的......
  • Redis管道Batch操作
    管道Batch操作privateasyncTaskAddTTL(){vardb=RDDB.RedisAgent.Database;Stopwatchsp=Stopwatch.StartNew();varbatch1=db.CreateBatch();for(inti=0;i<1000000;i++){......
  • 非标准库--conio.h库
    1.getch函数主要内容intgetch(void):所在头文件:conio.h函数用途:从控制台读取一个字符,但不显示在屏幕上,即一个不需要通过ENTER确定的getchar.函数原型:intgetch(void)返回值:读取的字符例如:charch;或intch;getch();或ch=getch();用getch();会等待你按下任意键,再继续......