最近想学netty,但平常工作中NIO用的比较少,所以最近就复习了下NIO。自己写了个基于NIO的echo例子,代码挺简单的。
echo 服务端代码
package study.nio.echo;
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;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EchoServer implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(EchoServer.class);
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
public EchoServer(int port) {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(port));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
LOGGER.error(e.getMessage());
System.exit(0);
}
}
@Override
public void run() {
if (selector.isOpen() == false) {
LOGGER.warn("echo server selector is not start");
return;
}
LOGGER.warn("echo server started");
while (true) {
try {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keysIter = selectedKeys.iterator();
while (keysIter.hasNext()) {
SelectionKey key = keysIter.next();
keysIter.remove();
if (key.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
LOGGER.info("echo server is connected");
sc.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
StringBuilder strb = new StringBuilder(1024);
while (sc.read(byteBuffer) > 0) {
byteBuffer.flip();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
byteBuffer.clear();
String msg = new String(bytes);
LOGGER.info("echo server read msg:" + msg);
strb.append(msg);
}
ByteBuffer writeBuffer = ByteBuffer.wrap(strb.toString().getBytes());
LOGGER.info("{}", writeBuffer.position());
LOGGER.info("{}", writeBuffer.limit());
sc.write(writeBuffer);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
echo 客户端代码
package study.nio.echo;
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.SocketChannel;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class EchoClient implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(EchoClient.class);
private Selector selector;
private SocketChannel socketChannel;
private ByteBuffer byteBuffer;
public EchoClient(String ip, int port) {
try {
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(ip, port));
socketChannel.register(selector, SelectionKey.OP_CONNECT);
} catch (IOException e) {
LOGGER.error(e.getMessage());
System.exit(0);
}
}
@Override
public void run() {
if (selector.isOpen() == false) {
LOGGER.warn("echo client selector is not start");
return;
}
LOGGER.warn("echo client started");
while (true) {
try {
if (selector.isOpen() == false) {
LOGGER.warn("selector is closed");
break;
}
selector.select();
Iterator<SelectionKey> ite = this.selector.selectedKeys().iterator();
while (ite.hasNext()) {
SelectionKey key = (SelectionKey) ite.next();
ite.remove();
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key.channel();
// 如果正在连接,则完成连接
if (channel.isConnectionPending()) {
channel.finishConnect();
}
LOGGER.info("echo client is connected");
// 设置成非阻塞
channel.configureBlocking(false);
channel.write(ByteBuffer.wrap("this echo client msg,over".getBytes()));
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
StringBuilder strb = new StringBuilder(1024);
while (sc.read(byteBuffer) > 0) {
byteBuffer.flip();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
byteBuffer.clear();
String msg = new String(bytes);
strb.append(msg);
}
LOGGER.info("echo client read msg:" + strb.toString());
break;
}
}
} catch (IOException e) {
LOGGER.error(e.getMessage());
System.exit(0);
}
}
}
}
启动测试的代码
package study.nio.echo;
public class EchoTest1 {
public static void main(String[] args) {
EchoClient echoClient = new EchoClient("127.0.0.1", EchoTest.serverPort);
echoClient.run();
}
}
package study.nio.echo;
public class EchoTest1 {
public static void main(String[] args) {
EchoClient echoClient = new EchoClient("127.0.0.1", EchoTest.serverPort);
echoClient.run();
}
}
分享到:
相关推荐
java基于nio的通信实例,带UML结构图及server、client源码。
java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...
基于NIO的socket举例 基于NIO的socket举例 基于NIO的socket举例 基于NIO的socket举例 基于NIO的socket举例基于NIO的socket举例 基于NIO的socket举例
基于事件的 NIO 多线程服务器
NioServer.java
NioSocket,包括server端和client端。server端有自动判定client掉线机制,client端有自动重连机制。本人已在项目实用,未经允许禁止转载!
基于NIO的多线程聊天系统,代码很少,很经典,51CTO网站上的代码。有登陆和聊天界面。代码结构层次清晰,系统只有6个类。
基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现五子棋游戏.zip基于Java NIO实现五子棋游戏.zip 基于Java NIO实现...
基于nio 简易聊天室的服务端 客户端,有界面
基于NIO的聊天室
相比于上次的基于BIO的多人聊天室的线程数量大幅度减少。 一个线程用于监听客户端的到达,两个线程池分别负责客户端 消息的 读 和写。 另外两个线程 负责 readSelector 和writeSelector 的监听。 但是仅仅是对 ...
Ioserver java Nio socket 框架 是个不错的NIO 通讯框架,本来想学习mina框架,看了看mina的源码太头痛,本人觉得看懂了Ioserver 再看mina的框架,想多的学习 java NIO 的也可以下载 看看,很值得学习啊!!!
基于NIO编写的聊天室,命令行运行,分server,client,config三个包,分别存放服务器端,客户端,以及一些端口信息的配置类。
基于NIO的远程调用框架的设计与实现 master
tuna 是一个基于NIO的简单http服务器,简单的实现了反向代理和负载均衡 这是tuna的配置文件 #this is config file for tuna #some common config keepalived: 5000 username: root password: root proxyServer: ...
java nio 服务器范例及j2me代码连接服务器的测试代码。
基于NIO简单实现网络聊天功能
同时整个服务端的流程处理,建立于事件机制上。在 [接受连接->读->业务处理->写 ->关闭连接 ]这个 过程中,触发器将触发相应事件,由事件处理器对相应事件分别响应,完成服务器端的业务处理。...
适合于文件小但数量比较大的文件传输 传输速度比传统的流IO要快很多,刚接触nio不久,希望有朋友能对它再进行优化,相信很多项目里用的上
NULL 博文链接:https://marcocs410.iteye.com/blog/981157