Java Socket、SocketServer的读写、连接事件监听,都是阻塞式的。Java提供了另外一种非阻塞式读写、连接事件监听方式——NIO。本文简单的介绍一个NIO Socket入门例子,原理以及详细用法,参考后续文章

服务端代码

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.Iterator; /**
*
* NIO Socket Server
* @author coshaho
*/
public class NIOServer
{
public static void main(String[] args) throws IOException
{
// 启动Socket Server Channel
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(8001));
server.configureBlocking(false); // 绑定选择器,注册连接监听事件
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT); SelectorHandler handler = new SelectorHandler();
while(true)
{
// 非阻塞监听注册事件
if(selector.select(2000) == 0)
{
System.out.println("No selection");
continue;
} // 发现注册事件,依次处理
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while(keyIter.hasNext())
{
SelectionKey key = keyIter.next();
if(key.isAcceptable())
{
handler.doAccept(key);
} if(key.isReadable())
{
handler.doRead(key);
} if(key.isValid() && key.isWritable())
{
handler.doWrite(key);
} keyIter.remove();
}
}
} /**
* 事件处理器
* @author h00219638
*/
public static class SelectorHandler
{
// 连接请求处理
public void doAccept(SelectionKey key) throws IOException
{
SocketChannel socket = ((ServerSocketChannel)key.channel()).accept();
socket.configureBlocking(false);
// 注册数据读取事件
socket.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(1024));
} public void doRead(SelectionKey key) throws IOException
{
SocketChannel socket = (SocketChannel)key.channel(); // 也可以临时分配ByteBuffer
ByteBuffer buf = (ByteBuffer) key.attachment();
buf.clear(); if(-1 == socket.read(buf))
{
socket.close();
}
else
{
System.out.println("Server received: " + new String(buf.array(), 0, buf.limit())); /**
* public static final int OP_READ = 1 << 0;
public static final int OP_WRITE = 1 << 2;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_ACCEPT = 1 << 4;
*/
// 增加写事件,写事件会不断被触发,数据写完后必须取消写事件监听
key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
}
} public void doWrite(SelectionKey key) throws IOException
{
SocketChannel socket = (SocketChannel)key.channel();
ByteBuffer buf = (ByteBuffer) key.attachment(); // 写数据之前注意调用flip方法,重置指针
buf.flip();
System.out.println("Write: " + new String(buf.array(), 0, buf.limit()));
socket.write(buf);
if(!buf.hasRemaining())
{
// 取消写事件监听
key.interestOps(key.interestOps() &~ SelectionKey.OP_WRITE);
}
buf.compact();
}
} }

客户端代码

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; import org.drools.core.util.StringUtils; /**
*
* NIO Socket Client
* @author coshaho
*/
public class NIOClient
{
public static void main(String[] args) throws IOException
{
SocketChannel socket = SocketChannel.open();
socket.configureBlocking(false); if(!socket.connect(new InetSocketAddress("localhost", 8001)))
{
System.out.println("Not connect");
// 正真的连接
while(!socket.finishConnect())
{
System.out.println("Not finishConnect");
}
} ByteBuffer wBuf = ByteBuffer.wrap("Hello, server".getBytes());
while(wBuf.hasRemaining())
{
socket.write(wBuf);
} ByteBuffer rBuf = ByteBuffer.allocate(8);
StringBuffer sBuf = new StringBuffer();
while(-1 != (socket.read(rBuf)))
{
rBuf.flip();
String s = new String(rBuf.array(), 0, rBuf.limit());
sBuf.append(s);
rBuf.clear();
if(StringUtils.isEmpty(s))
{
break;
} } System.out.println("Client received: " + sBuf.toString());
socket.close();
}
}

Java Socket NIO入门的更多相关文章

  1. Java Socket NIO详解(转)

    java选择器(Selector)是用来干嘛的? 2009-01-12 22:21jsptdut | 分类:JAVA相关 | 浏览8901次 如题,不要贴api的,上面的写的我看不懂希望大家能给我个通 ...

  2. Java Socket NIO示例总结

    Java NIO是非阻塞IO的实现,基于事件驱动,非常适用于服务器需要维持大量连接,但是数据交换量不大的情况,例如一些即时通信的服务等等,它主要有三个部分组成: Channels Buffers Se ...

  3. Java Socket(1): 入门

    前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据.故把Socket的基础知识总结梳理一遍. 一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那 ...

  4. java socket nio编程

    上次写了一个socket的基本编程,但是有个问题,阻塞特别严重,于是小编便去找了nio学习了一下... public class TimeServer { public static void mai ...

  5. Java Socket NIO

    服务端: public class NIOServer { private static final String HOST = "localhost"; private stat ...

  6. 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!

    本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...

  7. Java NIO入门(二):缓冲区内部细节

    Java NIO 入门(二)缓冲区内部细节 概述 本文将介绍 NIO 中两个重要的缓冲区组件:状态变量和访问方法 (accessor). 状态变量是前一文中提到的"内部统计机制"的 ...

  8. Java NIO入门

    NIO入门 前段时间在公司里处理一些大的数据,并对其进行分词.提取关键字等.虽说任务基本完成了(效果也不是特别好),对于Java还没入门的我来说前前后后花了2周的时间,我自己也是醉了.当然也有涉及到机 ...

  9. Java NIO 入门

    本文主要记录 Java 中  NIO 相关的基础知识点,以及基本的使用方式. 一.回顾传统的 I/O 刚接触 Java 中的 I/O 时,使用的传统的 BIO 的 API.由于 BIO 设计的类实在太 ...

随机推荐

  1. python全栈开发day12

    列表 创建列表: 基本操作: 索引 切片 追加 删除 长度 切片 循环 包含 #######################列表list类中提供的方法######################## ...

  2. LED客显的类

    using System; using System.IO.Ports; namespace Common { public class LedHelper { ; private static st ...

  3. TensorFlow安装之后导入报错:libcudnn.so.6:cannot open sharedobject file: No such file or directory

    转载自:http://blog.csdn.net/silent56_th/article/details/77587792 系统环境:Ubuntu16.04 + GTX1060 目的:配置一下pyth ...

  4. SpringMVC(三):参数绑定、输入输出转换

    一.参数解析绑定 1. 自定义绑定:不绑定某些项 @InitBinder private void initBinder(WebDataBinder dataBinder) { dataBinder. ...

  5. MySQL crash-safe replication【转载】

    本文来自david大神的博客,innodb技术内幕的作者. http://insidemysql.blog.163.com/blog/static/202834042201385190333/ MyS ...

  6. sql server 复制常见问题及查看

    1.SQL Server同步复制问题排查方法http://blog.csdn.net/roy_88/article/details/41481059 2.[同步复制常见错误处理1]当IDENTITY_ ...

  7. 前端 HTML标签属性

    HTML标签可以设置属性,如下: <div id="i1">这是一个div标签</div> <p class='p1 p2 p3'>这是一个段落 ...

  8. linux下automake用法

    linux下automake用法 2017年02月06日 09:21:14 阅读数:3684 标签: makemakefilegnulinux   作为Linux下的程序开发人员,大家一定都遇到过Ma ...

  9. JAVA代码(GET方式)请求URL(HTTP,HTTPS)

    /** * * @param url 这个只支持http地址,不支持https * @param request * @return */ public static String sendMessa ...

  10. Cocos Creator 计时器的延时循环试用方法

    *****计时器的一些运用***** //计算1次的计时器,2秒后执行 this.scheduleOnce(function(){ this.doSomething(); },2); //每隔5秒执行 ...