网络编程 -- RPC实现原理 -- NIO单线程
啦啦啦
Class : Service
package lime.pri.limeNio.optimize.socket; import java.io.ByteArrayOutputStream;
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.Date;
import java.util.Iterator;
import java.util.Set; /**
* 单线程NIO
*
* @author lime
*
*/
public class Service { public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
System.out.println("监听端口@9999,等待客户端连接...");
int n = selector.select();
System.out.println("事件就绪通道个数 : " + n);
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
if (selectionKey.isAcceptable()) {
System.out.println("-- -- -- 处理Acceptable事件");
ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
System.out.println("-- -- -- 处理Readable事件");
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.clear();
SocketChannel sc = (SocketChannel) selectionKey.channel();
sc.read(byteBuffer);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(byteBuffer.array());
System.out.println("客户端( " + sc.getRemoteAddress() + " ) 请求 : " + bos.toString());
sc.register(selector, SelectionKey.OP_WRITE);
} else if (selectionKey.isWritable()) {
System.out.println("-- -- -- 处理Writable事件");
String response = "服务端响应 : " + new Date().toString();
ByteBuffer byteBuffer = ByteBuffer.wrap(response.getBytes());
SocketChannel sc = (SocketChannel) selectionKey.channel();
sc.write(byteBuffer);
sc.close();
}
}
}
}
}
Class : Client
package lime.pri.limeNio.optimize.socket; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; public class Client { public static void main(String[] args) throws IOException {
for (int i = 0; i < 10; i++) {
new Thread() {
{
setDaemon(false);
} public void run() {
try {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999)); socketChannel.write(ByteBuffer.wrap("Query Date".getBytes()));
socketChannel.shutdownOutput();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
socketChannel.read(byteBuffer);
System.out.println(new String(byteBuffer.array()));
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
};
}.start();
}
}
}
Console : Server
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 1
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 1
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2689 ) 请求 : Query Date
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 1
-- -- -- 处理Writable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 1
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 2
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2690 ) 请求 : Query Date
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Writable事件
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2691 ) 请求 : Query Date
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Writable事件
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2692 ) 请求 : Query Date
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2693 ) 请求 : Query Date
-- -- -- 处理Writable事件
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Writable事件
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2694 ) 请求 : Query Date
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2695 ) 请求 : Query Date
-- -- -- 处理Writable事件
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Writable事件
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2696 ) 请求 : Query Date
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 3
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2697 ) 请求 : Query Date
-- -- -- 处理Writable事件
-- -- -- 处理Acceptable事件
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 2
-- -- -- 处理Writable事件
-- -- -- 处理Readable事件
客户端( /127.0.0.1:2698 ) 请求 : Query Date
监听端口@9999,等待客户端连接...
事件就绪通道个数 : 1
-- -- -- 处理Writable事件
监听端口@9999,等待客户端连接...
Console : Client
Thread[Thread-7,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-0,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-3,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-9,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-1,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-4,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-6,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-5,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-8,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
Thread[Thread-2,5,main] 服务端响应 : Sat Jun 24 16:00:41 CST 2017
啦啦啦
网络编程 -- RPC实现原理 -- NIO单线程的更多相关文章
- 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V1
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V1——设置标识变量selectionKey.attach(true);只处理一次(会一直循环遍历selectionKeys,占用CPU资源). ( ...
- 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V2
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2——增加WriteQueue队列,存放selectionKey.addWriteEventToQueue()添加selectionKey并唤醒阻 ...
- 网络编程 -- RPC实现原理 -- 目录
-- 啦啦啦 -- 网络编程 -- RPC实现原理 -- NIO单线程 网络编程 -- RPC实现原理 -- NIO多线程 -- 迭代版本V1 网络编程 -- RPC实现原理 -- NIO多线程 -- ...
- 网络编程 -- RPC实现原理 -- Netty -- 迭代版本V1 -- 入门应用
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V1——Netty入门应用 Class : NIOServerBootStrap package lime.pri.limeNio.netty.ne ...
- 网络编程 -- RPC实现原理 -- Netty -- 迭代版本V2 -- 对象传输
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2——Netty -- 使用序列化和反序列化在网络上传输对象:需要实现 java.io.Serializable 接口 只能传输( ByteBuf ...
- 网络编程 -- RPC实现原理 -- Netty -- 迭代版本V3 -- 编码解码
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2——Netty -- pipeline.addLast(io.netty.handler.codec.MessageToMessageCodec ...
- 网络编程 -- RPC实现原理 -- Netty -- 迭代版本V4 -- 粘包拆包
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V2——Netty -- new LengthFieldPrepender(2) : 设置数据包 2 字节的特征码 new LengthFieldB ...
- 网络编程 -- RPC实现原理 -- RPC -- 迭代版本V3 -- 远程方法调用 整合 Spring
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V3——RPC -- 远程方法调用 及 null的传输 + Spring 服务提供商: 1. 配置 rpc03_server.xml 注入 服务提供 ...
- 网络编程 -- RPC实现原理 -- RPC -- 迭代版本V4 -- 远程方法调用 整合 Spring 自动注册
网络编程 -- RPC实现原理 -- 目录 啦啦啦 V4——RPC -- 远程方法调用 + Spring 自动注册 服务提供商: 1. 配置 rpc04_server.xml 注入 服务提供商 rpc ...
随机推荐
- copy unicode HTML to clipboard
How to copy unicode HTML code to the clipboard in html format, so it can be pasted into Writer, Word ...
- SharePoint 2019 图文安装教程
前言 SharePoint 2019刚刚发布,很多群友在寻找安装教程,霖雨正好也下载了进行体验,就把完整的安装过程做成图文教程,分享给大家了,有需要的人可以有个参考. 文章从创建虚拟机开始,可能有点啰 ...
- VS2010链接TFS遇见错误:TF204017,没有访问工作区域,需要一个或者多个必须权限
最近刚刚搭建好服务器,然后准备将VSS源代码迁移到TFS源代码管理服务器上面.在我本机先用的服务器帐号来上传初始化源代码数据库,然后我又用自己的帐号进行迁出代码的时候发生的异常. 造成上述错误,主要是 ...
- C调用lua的table里面的函数
网上搜索C.C++调用lua函数,有一大堆复制粘贴的. 但是搜索<C调用lua的table里面的函数> 怎么就没几个呢? 经过探索,发现其实逻辑是这样的: 1.根据name获取table ...
- C# ConcurrentQueue实现
我们从C# Queue 和Stack的实现知道Queue是用数组来实现的,数组的元素不断的通过Array.Copy从一个数组移动到另一个数组,ConcurrentQueue我们需要关心2点:1线程安全 ...
- Bootstrap 标签页(Tab)插件
摘自: http://www.runoob.com/bootstrap/bootstrap-tab-plugin.html Bootstrap 标签页(Tab)插件 标签页(Tab)在 Bootstr ...
- fetch使用的常见问题及其解决办法
摘自: https://segmentfault.com/a/1190000008484070 fetch使用的常见问题及其解决办法 javascript wonyun 2月25日发布 | 0 收 ...
- .NET 并行编程——数据并行
本文内容 并行编程 数据并行 环境 计算 PI 矩阵相乘 把目录中的全部图片复制到另一个目录 列出指定目录中的所有文件,包括其子目录 最近,对多线程编程,并行编程,异步编程,这三个概念有点晕了,之前我 ...
- 微软BI 之SSIS 系列 - Lookup 组件的使用与它的几种缓存模式 - Full Cache, Partial Cache, NO Cache
开篇介绍 先简单的演示一下使用 Lookup 组件实现一个简单示例 - 从数据源表 A 中导出数据到目标数据表 B,如果 A 数据在 B 中不存在就插入新数据到B,如果存在就更新B 和 A 表数据保持 ...
- Java通过JNI调用C++程序
JNI是Java Native Interface的缩写,中文为JAVA本地调用.使用JNI可以很方便的用我们的Java程序调用C/C++程序.很多时候,某些功能用Java无法实现,比如说涉及到底层驱 ...