Client:客户端

package aio;

import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException; /**
*
* @Description:异步非阻塞
* @date 2018年8月4日,下午4:06:55
*/
public class Client implements Runnable{ //异步客户端通道
private AsynchronousSocketChannel asc ; //调用客户端则打开通道
public Client() throws Exception {
asc = AsynchronousSocketChannel.open();
} //客户端的连接
public void connect(){
asc.connect(new InetSocketAddress("127.0.0.1", 8765));
} //写操作
public void write(String request){
try {
//把客户端的数据写入缓冲区交给服务端
asc.write(ByteBuffer.wrap(request.getBytes())).get();
read();
} catch (Exception e) {
e.printStackTrace();
}
} //读操作
private void read() {
//创建字节缓冲区大小
ByteBuffer buf = ByteBuffer.allocate(1024);
try {
//读取服务端响应的数据
asc.read(buf).get();
//复位
buf.flip();
byte[] respByte = new byte[buf.remaining()];
buf.get(respByte);
System.out.println("读取服务器响应的数据----》"+new String(respByte,"utf-8").trim());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//防止程序停止运行
@Override
public void run() {
while(true){ }
} public static void main(String[] args) throws Exception {
//new一个Client客户端,则打开一个客户端通道
Client c1 = new Client();
c1.connect(); Client c2 = new Client();
c2.connect(); Client c3 = new Client();
c3.connect(); new Thread(c1, "c1").start();
new Thread(c2, "c2").start();
new Thread(c3, "c3").start(); Thread.sleep(1000); c1.write("c1 aaa");
c2.write("c2 bbbb");
c3.write("c3 ccccc");
} } Client:客户端

Server:服务器端

package aio;

import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Server {
//线程池
//jdk api功能说明:一个Executor,提供管理终止的方法和可以生成Future的方法,用于跟踪一个或多个异步任务的进度。
private ExecutorService executorService;
//线程组
private AsynchronousChannelGroup threadGroup;
//服务器通道
//jdk api功能说明:用于资源共享的一组异步通道。
public AsynchronousServerSocketChannel assc; public Server(int port){
try {
//创建一个缓存池
executorService = Executors.newCachedThreadPool();
//创建线程组
//jdk api功能说明:创建具有给定线程池的异步通道组,该线程池根据需要创建新线程。
threadGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
//打开服务器通道
assc = AsynchronousServerSocketChannel.open(threadGroup);
//进行绑定
assc.bind(new InetSocketAddress(port)); System.out.println("server start , port : " + port);
//进行阻塞
assc.accept(this, new ServerCompletionHandler());
//一直阻塞 不让服务器停止
Thread.sleep(Integer.MAX_VALUE); } catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args) {
Server server = new Server(8765);
} }

ServerCompletionHandler:服务器端数据处理

package aio;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException; /**
* @Description:服务器数据处理
* @date 2018年8月5日,下午12:35:39
*/
//CompletionHandler<AsynchronousSocketChannel, Server>:AsynchronousSocketChannel是固定不变的,Server:是指服务器类
//必须覆写成功completed()和失败failed()两个方法
public class ServerCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Server> { @Override
public void completed(AsynchronousSocketChannel asc, Server attachment) {
//当有下一个客户端接入的时候 直接调用Server的accept方法,这样反复执行下去,保证多个客户端都可以阻塞
//使用递归
attachment.assc.accept(attachment, this);
read(asc);
} private void read(final AsynchronousSocketChannel asc) {
//读取数据
ByteBuffer buf = ByteBuffer.allocate(1024);
asc.read(buf, buf, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer resultSize, ByteBuffer attachment) {
//进行读取之后,重置标识位
attachment.flip();
//获得读取的字节数
System.out.println("Server -> " + "收到客户端的数据长度为:" + resultSize);
//获取读取的数据
String resultData = new String(attachment.array()).trim();
System.out.println("Server -> " + "收到客户端的数据信息为:" + resultData);
String response = "服务器响应, 收到了客户端发来的数据: " + resultData;
write(asc, response);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
} private void write(AsynchronousSocketChannel asc, String response) {
try {
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(response.getBytes());
buf.flip();
asc.write(buf).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} @Override
public void failed(Throwable exc, Server attachment) {
exc.printStackTrace();
} }

AIO异步非阻塞学习的更多相关文章

  1. NIO:异步非阻塞I/O,AIO,BIO

    Neety的基础使用及说明 https://www.cnblogs.com/rrong/p/9712847.html BIO(缺乏弹性伸缩能力,并发量小,容易出现内存溢出,出现宕机 每一个客户端对应一 ...

  2. nginx学习(二)——基础概念之异步非阻塞

    上面讲了很多关于nginx的进程模型,接下来,我们来看看nginx是如何处理事件的. 有人可能要问了,nginx采用多worker的方式来处理请求,每个worker里面只有一个主线程,那能够处理的并发 ...

  3. python学习笔记之四-多进程&多线程&异步非阻塞

    ProcessPoolExecutor对multiprocessing进行了高级抽象,暴露出简单的统一接口. 异步非阻塞 爬虫 对于异步IO请求的本质则是[非阻塞Socket]+[IO多路复用]: & ...

  4. 异步非阻塞IO的Python Web框架--Tornado

    Tornado的全称是Torado Web Server,从名字上就可知它可用作Web服务器,但同时它也是一个Python Web的开发框架.最初是在FriendFeed公司的网站上使用,FaceBo ...

  5. 基于MFC的socket编程(异步非阻塞通信)

       对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清, ...

  6. flask 实现异步非阻塞----gevent

    我们都知道,flask不支持异步非阻塞的请求,我们可以创建一个新项目去测试一下,推荐大家使用pycharm去开发我们的flask  使用特别的方便. rom flask import Flask im ...

  7. 在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树

    nginx平台初探(100%) — Nginx开发从入门到精通 http://ten 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来 ...

  8. Python web框架 Tornado(二)异步非阻塞

    异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案:多线程,多进程 异步非阻塞(存在IO请求): Torna ...

  9. Linux-同步异步非阻塞阻塞的解析

    一.理解同步.异步.阻塞.非阻塞 出场人物:老张,水壶两把(普通水壶,简称水壶:会响的水壶,简称响水壶). 1 老张把水壶放到火上,立等水开.(同步阻塞) 老张觉得自己有点傻. 2 老张把水壶放到火上 ...

随机推荐

  1. leetcode-11-盛水最多的容器

    题目描述: 方法一:双指针 class Solution: def maxArea(self, height: List[int]) -> int: left = 0 right = len(h ...

  2. RabbitMQ 连接不上

    问题 [org.springframework.amqp.AmqpIOException: java.io.IOException] 解决 username: guest password: gues ...

  3. JavaScript——基本语法

    单词掌握 BOM 浏览器对象模型 DOM 文档对象模型 document 文档 break 中断 continue 继续 1.js脚本位置 通常可以在三个地方编写js脚本代码,一是在网页文件的< ...

  4. hibernate_02_hibernate的入门

    1.什么是Hibernate框架? Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接 ...

  5. Pycharm新建文档的模板设置

    下图演示的是关于python的文档的模板设置! 这样,以后的每一个新建的python的py文件,开头都会有下图中的两句:解释器路径与编码方式 步聚5的第二行内容打错了,应该是utf: #!/usr/b ...

  6. day 51 阿里iconfont的使用

    阿里iconfont的使用   1. 找到阿里巴巴图标库 2.找到图标 3.搜索你想要的图标 4.将图标添加到购物车 5.点击右上角的购物车按钮,我这里添加了两个. 6.提示你登陆,不需要花钱,找其中 ...

  7. HTML5伪类选择器表单验证

    input : required   选择必填表单域 input : focus : invalid 选择当前聚焦的且含有非法输入值的表单域 input : focus : valid 选择当前聚焦的 ...

  8. 面试系列24 dubbo负载均衡策略和集群容错策略

    (1)dubbo负载均衡策略 1)random loadbalance 默认情况下,dubbo是random load balance随机调用实现负载均衡,可以对provider不同实例设置不同的权重 ...

  9. 数据库DQL、DML、DDL及DCL详解

    目录 1. 数据查询语言(DQL,Data Query Language) 2. 数据操纵语言(DML,Data Manipulation Language) 3. 数据定义语言(DDL,Data D ...

  10. JS流程控制语句 退出循环break 在while、for、do...while、while循环中使用break语句退出当前循环,直接执行后面的代码。

    退出循环break 在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. 格式如下: for(初始条件;判断条件;循环后条件值更新) { i ...