基于Selector+Channel+线程池的server & client
来源:互联网 发布:禁止网络标语 编辑:程序博客网 时间:2024/06/10 21:11
server:
package com.tang.selector;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * Created by TangXW on 2017/8/11. */public class TimeServer { private static ExecutorService executor; static{ executor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000)); } public static void main(String[] args) throws IOException{ ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(8080)); ssc.configureBlocking(false); Selector selector = Selector.open(); ssc.register(selector, ssc.validOps()); while(true){ // 如果不设置连接超时,那么这个方法一直是阻塞的 int readCount = selector.select(1000); if(readCount == 0){ continue; } Set<SelectionKey> selectionKeySets = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectionKeySets.iterator(); while(keyIterator.hasNext()){ SelectionKey selectionKey = keyIterator.next(); if(selectionKey.isValid()){ // 此键是否有效 // 表示是serversocketchannel if(selectionKey.isAcceptable()){ ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = server.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); } // 表示SocketChannel if(selectionKey.isReadable()){ executor.submit(new TimeServerTask(selectionKey)); } keyIterator.remove(); } } } }}
servertask:
package com.tang.selector;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.SocketChannel;import java.util.Calendar;/** * Created by TangXW on 2017/8/11. */public class TimeServerTask implements Runnable{ private SelectionKey selectionKey; public TimeServerTask(SelectionKey selectionKey){ this.selectionKey = selectionKey; } @Override public void run() { SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024); try{ int count = 0; // 如果从socketchannel中有数据 while((count = channel.read(byteBuffer)) > 0){ byteBuffer.flip(); byte[] request = new byte[byteBuffer.remaining()]; byteBuffer.get(request); String requestStr = new String(request); byteBuffer.clear(); if(!"GET CURRENT TIME".equals(requestStr)){ channel.write(byteBuffer.put("BAD_REQUEST".getBytes())); }else{ // 写入当前的时间戳 byteBuffer.put(Calendar.getInstance().getTime().toLocaleString().getBytes()); byteBuffer.flip(); channel.write(byteBuffer); } } } catch (IOException e){ e.printStackTrace(); selectionKey.cancel(); } }}
client:
package com.test.nio;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;/** * Created by TangXW on 2017/8/11. */public class TimeClient2 { //连接超时时间 static int connectTimeOut = 3000; static ByteBuffer buffer = ByteBuffer.allocateDirect(1024); public static void main(String[] args) throws IOException, InterruptedException { SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(8080)); socketChannel.configureBlocking(false); long start = System.currentTimeMillis(); while (!socketChannel.finishConnect()){ if (System.currentTimeMillis() - start >= connectTimeOut){ throw new RuntimeException("尝试建立连接超过3秒"); } } // 如果走到这一步,说明连接建立成功 while (true){ buffer.put("GET CURRENT TIME".getBytes()); buffer.flip(); socketChannel.write(buffer); buffer.clear(); // 清空然后将传过来的数据重新写入 if(socketChannel.read(buffer) > 0){ buffer.flip(); byte[] response = new byte[buffer.remaining()]; buffer.get(response); System.out.println("reveive response:" + new String(response)); buffer.clear(); } Thread.sleep(5000); } }}
output:
reveive response:2017-8-14 13:33:31reveive response:2017-8-14 13:33:36reveive response:2017-8-14 13:33:41reveive response:2017-8-14 13:33:46reveive response:2017-8-14 13:33:51...
阅读全文
0 0
- 基于Selector+Channel+线程池的server & client
- Selector Channel
- 基于NIO的Client/Server程序实践
- 基于I/O的Server/Client实现
- 基于TCP/UDP的Server-Client
- 【Netty入门】基于Netty的Server / Client
- 基于TCP的server和client编写。
- 基于WinSocket的单线程Client的实现
- vs2008 MFC 线程池实现的完整的 Client/Server Socket通讯类
- WebSocket 基于 Tomcat7.0.54 的server部署 与client访问
- 实现基于TCP/IP协议的简单Client/Server程序
- 【NIO详解】基于NIO的client与server
- JavaSE socket 基于UDP Server/Client的实现
- 基于EPOLL+多进程+线程池的server框架设想
- Socket Server-基于线程池的TCP服务器
- 一个完整的包含server,admin,client,其中server使用express搭建,admin和client基于vue开发。
- Java网络编程之多线程Client-Server
- NIO之channel与selector
- Codeforces 745C Hongcow Builds A Nation
- 堆和栈的区别
- poj 1258 Agri-Net 最经典的MST★
- join,left join,right join
- 给tabBar设置图片和字体颜色 navigationBar设置字体大小 颜色
- 基于Selector+Channel+线程池的server & client
- GCC编译器中的-I -L -l 选项。
- C++: *max_element函数和*min_element函数
- 设置tomcat的默认项目名称(默认应用)、端口号,访问连接(url)不需要输入项目名称、端口
- USACO Section 1.3 Mixing Milk
- SpringMVC学习(1)
- ecplisse配置代码格式化模版
- Codeforces Round #428 (Div. 2) D. Winter is here(容斥,补题)
- Qt5插件开发