首页 技术 正文
技术 2022年11月6日
0 收藏 865 点赞 991 浏览 4166 个字

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();
}}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,030
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,859