Java Socket NIO入门
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入门的更多相关文章
- Java Socket NIO详解(转)
java选择器(Selector)是用来干嘛的? 2009-01-12 22:21jsptdut | 分类:JAVA相关 | 浏览8901次 如题,不要贴api的,上面的写的我看不懂希望大家能给我个通 ...
- Java Socket NIO示例总结
Java NIO是非阻塞IO的实现,基于事件驱动,非常适用于服务器需要维持大量连接,但是数据交换量不大的情况,例如一些即时通信的服务等等,它主要有三个部分组成: Channels Buffers Se ...
- Java Socket(1): 入门
前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据.故把Socket的基础知识总结梳理一遍. 一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那 ...
- java socket nio编程
上次写了一个socket的基本编程,但是有个问题,阻塞特别严重,于是小编便去找了nio学习了一下... public class TimeServer { public static void mai ...
- Java Socket NIO
服务端: public class NIOServer { private static final String HOST = "localhost"; private stat ...
- 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!
本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...
- Java NIO入门(二):缓冲区内部细节
Java NIO 入门(二)缓冲区内部细节 概述 本文将介绍 NIO 中两个重要的缓冲区组件:状态变量和访问方法 (accessor). 状态变量是前一文中提到的"内部统计机制"的 ...
- Java NIO入门
NIO入门 前段时间在公司里处理一些大的数据,并对其进行分词.提取关键字等.虽说任务基本完成了(效果也不是特别好),对于Java还没入门的我来说前前后后花了2周的时间,我自己也是醉了.当然也有涉及到机 ...
- Java NIO 入门
本文主要记录 Java 中 NIO 相关的基础知识点,以及基本的使用方式. 一.回顾传统的 I/O 刚接触 Java 中的 I/O 时,使用的传统的 BIO 的 API.由于 BIO 设计的类实在太 ...
随机推荐
- MySQL+InnoDB semi-consitent read原理及实现分析(转)
add by zhj: 主要讲的是在MySQL在Repeatable Read和Read Committed级别下,加锁时的不同,在Read Committed隔离级别下,只对where 中满足条件的 ...
- sed命令 windows与linux换行
Linux的Bash命令中有一个sed操作,SSD的create_list.sh中有用到这个操作: 结合着下面这个解释: 也就是删除所有行里面的以VOC2007/Annotations/(这里的\代表 ...
- 用Eclipse构建Maven项目
Eclipse中m2eclipse插件的安装 Help>Install New Software Click Add Name: m2e Location: http://download.ec ...
- MyEclipse下创建的项目 导入eclipse
1.导入在MyEclipse下创建的项目 2.把项目变成Web项目,在项目上右键-->Properties-->选择Project Facets-->点击Convert to fac ...
- Advising controllers with the @ControllerAdvice annotation
The @ControllerAdvice annotation is a component annotation allowing implementation classes to be aut ...
- java实现消息队列的两种方式
https://blog.csdn.net/fenfenguai/article/details/79257928
- mysql常用压测工具
关键字:mysql压测工具 mysqlslap.sysbench 基准测试sysbench 压力测试 tpcc 具体怎么使用百度
- ETL : kettle Spoon 转换 + 作业
Kettle能做什么? 前言 : 需将db2中数据导入到mysql中,利用etl工具进行多表转换.以此为切入点,系统整理.学习kettle工具. 提醒: kettle是纯java编写,机器需要有jre ...
- 线上MYSQL同步报错故障处理方法总结
前言 在发生故障切换后,经常遇到的问题就是同步报错,下面是最近收集的报错信息. 记录删除失败 在master上删除一条记录,而slave上找不到 Last_SQL_Error: Could not e ...
- git diff 与 git diff --cached的不用
git diff比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容.若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命 ...