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. 漫画:什么是HashMap

    漫画:什么是HashMap 参考: HashMap源码解析 美团技术团队:Java 8系列之重新认识HashMap

  2. 【托业】【新托业TOEIC新题型真题】学习笔记5-题库二->P7

    --------------------------------------单词-------------------------------------- amenity 适意:休闲设施 onsit ...

  3. vue package-lock.json的作用

    其实用一句话来概括很简单,就是锁定安装时的包的版本号,并且需要上传到git,以保证其他人在npm install时大家的依赖能保证一致.

  4. 20181223 python 使用Beautiful Soup

    (这篇,没什么营养价值) 怎么说呢! 爬虫吧!把html页面进行解析得到有效数据,而beautiful soup 能快速格式化页面再进行方法对数进行提取,存入想要存入的DB中. from bs4 im ...

  5. 003-hive安装

    http://www.aboutyun.com/thread-6902-1-1.html http://www.aboutyun.com/thread-7374-1-1.html

  6. 多线程下的单例-double check

    话不多说直接上代码: public sealed class Singleton { private static Singleton _instance = null; // Creates an ...

  7. C++了解free和delete

    (转自:http://www.cnblogs.com/mrye/archive/2012/09/01/2667079.html) void MyMethod1() {     using namesp ...

  8. vue 后退不刷新页面

    使用 this.$router.push({path: '/aichat'})路由跳转方式跳转页面 要实现 home => chat  chat页面刷新: chat => report, ...

  9. Cell complex单元复合形

    概念 (1)Piecewise linear complex (PLC) 分段线性复合形 (2)Cell complex 单元复合形 [1] (元胞复合形) (3)Linear Cell Comple ...

  10. mysql数据具体操作

    1.建表操作 前面提到的是简单的建表,这里需要提到一下外键. create table userinfo2( id int auto_increment primary key, name ), ge ...