- 浏览: 229241 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
tonyyan:
谢谢分享!
Kafka 监控 -
dtyu100:
反手就是一个赞,这相当于是官网druid.io的中文版本,很厉 ...
Druid 大数据分析之快速应用(单机模式) -
sqy:
2018-04-12T01:30:27,527 ERROR [ ...
Druid 大数据分析之快速应用(单机模式) -
wangyudong:
学习了,不错的Spring boot实例,参考着很快写出了RE ...
Spring boot 入门实例 -
string2020:
servlet4规范出来了,求翻译
Java Servlet3.1规范
引用
本节采用JDK1.5之后java.util.concurrent包的API服务端实现线程池读取信息,可以接采用Executors工具快速创建线程池,也可以ExecutorService子类自定义创建。
客端连接服务端发送信息后关闭连接SOCKET短连接(HTTP为短连接),若采用SOCKET长连接,需要增加"心跳检测",本节暂未实现长连接。
因Selector轮询可读事件时,存在重读问题,解决办法是在读的代码块中加下述代码selectKey.cancel()或selectKey.interestOps(selectKey.interestOps() & (~SelectionKey.OP_READ))
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.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 服务端 */ public class SocketServer { /** * 服务器默认绑定端口 */ public static final int DEFAULT_PORT = 9999; /** * 选择器 */ private Selector selector; /** * 读取线程池 */ private ExecutorService pool; public SocketServer(String ip, int port) { ServerSocketChannel ssc = null; try { int _port = DEFAULT_PORT; if (port > 0) _port = port; /* 获取通道 */ ssc = ServerSocketChannel.open(); /* 配置非阻塞 */ ssc.configureBlocking(false); /** * 配置绑定端口 ServerSocketChannel没有bind()方法, * 因此有必要取出对等的ServerSocket并使用它来绑定到一 * 个端口以开始监听连接 */ ssc.socket().bind(new InetSocketAddress(ip, _port)); /* 获取选择器 */ this.selector = Selector.open(); /* 将通道注册到选择器 */ ssc.register(this.selector, SelectionKey.OP_ACCEPT); /** * 可以使用Executors,快速创建线程池,但是如果综合考虑 * CPU、内存等资及并发情况,可以采用自定方式创建池( * 拒绝处理等问题 * ),此处简单自定义创建读取池 * */ pool = new ThreadPoolExecutor(1, 2, 2000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(5)); } catch (IOException e2) { System.out.println("服务器启动失败!"); e2.printStackTrace(); try { if(ssc != null) ssc.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 轮询选择器 * @throws Exception */ public void pollSelect() throws Exception { /* (阻塞)轮询选择器,直到有事件 */ while (true) { int readyChannels = 0; /*选择器是否关闭*/ if(this.selector.isOpen()){ readyChannels = this.selector.select(); } if(readyChannels == 0) continue; /* 获取事件通知列表 */ Iterator<SelectionKey> it = this.selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey selectKey = it.next(); it.remove(); try { process(selectKey); } catch (Exception e) { e.printStackTrace(); } } } } /** * 事件处理 * @param selectKey */ public void process(SelectionKey selectKey) throws Exception{ /* 客户端连接事件 */ if (selectKey.isAcceptable()) { accept(selectKey); } else if (selectKey.isReadable()) { /* 可读事件 */ read(selectKey); /** * 解决重复读 * 或设置不关注读事件来解决重复 * selectKey.interestOps(selectKey.interestOps() & (~SelectionKey.OP_READ)); * */ selectKey.cancel(); } } /** * 连接事件 * @param selectKey */ public void accept(SelectionKey selectKey) throws Exception { SocketChannel sc = null; try { ServerSocketChannel ssc = (ServerSocketChannel) selectKey .channel(); sc = ssc.accept(); sc.configureBlocking(false); System.out.println("客户端:" + sc.socket().getInetAddress().getHostAddress()+"端口"+sc.socket().getPort() + " 已连接"); sc.register(this.selector, SelectionKey.OP_READ); } catch (Exception e) { if(sc!=null) sc.close(); throw new IOException("客户端已断开连接!"); } } /** * 可读事件 * @param selectKey */ public void read(SelectionKey selectKey) throws Exception{ SocketChannel sc = (SocketChannel) selectKey .channel(); /*提交线程池处理*/ pool.submit(new SocketServerReadThread(sc)); } public static void main(String[] args) { SocketServer ss = null; try { ss = new SocketServer("localhost", 9999); ss.pollSelect(); } catch (Exception e) { e.printStackTrace(); } } }
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; /** * 从线程中读信息 * @author oy * */ public class SocketServerReadThread implements Runnable{ private SocketChannel channel; public SocketServerReadThread(SocketChannel channel){ this.channel = channel; } @Override public void run() { try { // 创建读取的缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); channel.read(buffer); byte[] data = buffer.array(); ByteArrayInputStream bais = new ByteArrayInputStream(data); ObjectInputStream ois = new ObjectInputStream(bais); User user = (User)ois.readObject(); System.out.println("客户端:" + channel.socket().getInetAddress().getHostAddress()+"端口"+channel.socket().getPort() + " 消息: " + user.toString()); } catch (Exception e) { System.out.println("客户端已断开连接!"); try { if(channel != null) channel.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
发表评论
-
数据接入ElasticSearch方式培训PPT
2018-01-28 11:53 1833写道 数据接入ElasticSearch几种方式总结,涉及 ... -
Apache ftp tools 图片下载支持中文
2017-12-05 23:55 1207写道 Apache Commom net:1) 递归pat ... -
FtpURLConnection 图片下载编码问题
2017-12-05 23:13 816写道 问题:1)Web项目中下载图片,存在下载不全,丢失部 ... -
Kafka 监控
2017-11-18 00:31 5652背景概述 写道 kafka0.9及以前版本ka ... -
Spring Cloud之OAuth2
2017-07-08 12:04 11288备:附件中OAuth2 授权服务器实现源码及PPT 一 ... -
Spring Cloud之Configuration Server
2017-05-19 22:51 1458为什么用spring cloud config 写道 一 ... -
Java Servlet3.1规范
2016-11-25 20:33 1156目录 前言........................ ... -
JMX监控(MBean)
2016-11-23 22:16 4064一、引言 写道 随着企业 IT 规模的不断增长,IT 资 ... -
哈希表在JAVA中如何实现
2016-11-23 20:42 2869一、 复习一下基础知识 1. 截断低位与抹除高位 ... -
Spring boot 入门实例
2016-10-29 00:33 4819写道 Spring Boot是由Pivotal团队提供的全 ... -
Java计算两点经纬度距离及最短运行时间
2016-09-12 21:20 2492概述 经纬度在地图应用中常见,一般结合路网信息库, ... -
计算机软件开源技术、大数据技术等资源教程
2016-08-24 13:01 533基于时间序列化数据引擎排名,很多OLAP工具,根据自身业务 ... -
代码单元与代码点
2016-08-16 17:46 633代码单元与代码点 代码点指编码表(比如Unicode)中某 ... -
Java模块化解决方案
2016-08-15 00:19 4134网络上很多OSGi的文章上来就Activator实例, ... -
深入浅出ClassLoader
2016-08-13 17:06 717你真的了解ClassLoader吗? 这篇文章翻译自zer ... -
Generate axis server code from wsdl
2016-08-04 00:34 12091、为什么需要生成服 ... -
Spring DAO设计实战
2016-01-23 12:21 3202引用 提供不同数据源和方言实现智能分页,因Spring单例 ... -
JAVA NIO 之二
2016-01-14 00:35 1927引用 继上节利用JAVA NIO实现简单数据传,本节实现自定 ... -
JAVA NIO 之一
2016-01-12 14:14 1530传统IO 写道 网络传输 ... -
JAVA压缩图片并打成ZIP
2016-01-06 13:48 7344引用 JAVA 获取网络图片或本地图片压缩后打成ZIP,但 ...
相关推荐
java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...
Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) ...
Java NIO英文高清原版
Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...
讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用
java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...
java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...
java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...
java NIO.zip
java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...
java nio 读文件,java nio 读文件
java NIO技巧及原理解析,java IO原理,NIO框架分析,性能比较
JAVA NIO学习资料JAVA NIO学习资料
Java NIO测试示例
基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...
JavaNIO.pdf
java nio编程 非阻塞模式的通信 电子书 带目录标签
Many serious Java programmers, especially enterprise Java programmers, consider the new I/O API--called NIO for New Input/Output--the most important feature in the 1.4 version of the Java 2 Standard ...