版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012727852/article/details/78087275
MultiplexerTimerServer
TimeClient
package niostudy;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
/**
* Created by Administrator on 2017/8/6.
*/
public class MultiplexerTimerServer implements Runnable {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private volatile boolean stop;
/**
* 初始化多路复用器,绑定监听端口
*
* @param port
* @throws IOException
*/
public MultiplexerTimerServer(Integer port) throws IOException {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(port), 1024);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("this server is start at port " + port);
}
public void run() {
while (!stop) {
try {
selector.select(1000);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectionKeys.iterator();
//
SelectionKey key = null;
while (it.hasNext()) {
key = it.next();
it.remove();
try {
//轮询
handleInput(key);
} catch (Exception e) {
if (key != null) {
key.cancel();
if (key.channel() != null) {
key.channel().close();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//
//多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会自动去注册并关闭,所以无需重复释放资源
if (selector != null) {
try {
selector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 处理请求信息
*
* @param key
*/
private void handleInput(SelectionKey key) throws IOException {
if (key.isValid()) {
//如果注册的事件是接入事件
if (key.isAcceptable()) {
//获取服务端通道
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = ssc.accept();
socketChannel.configureBlocking(false);
//把这个socketChannel注册
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
//获取通道
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
Integer readByts = socketChannel.read(byteBuffer);
//如果有消息收到
if (readByts > 0) {
byteBuffer.flip();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
String body = new String(bytes, "UTF-8");
System.out.println("收到客户端发来的请求!!" + body);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
dowrite(socketChannel, format.format(new Date()));
} else if (readByts < 0) {//链路已经关闭,需要关闭ScoketChannel
key.cancel();
socketChannel.close();
} else {
//do dothing
}
}
}
}
private void dowrite(SocketChannel socketChannel, String data) throws IOException {
if (data != null && data.trim().length() > 0) {
byte[] bytes = data.getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length());
byteBuffer.put(bytes);
byteBuffer.flip();
socketChannel.write(byteBuffer);
}
}
}
TimeServer
package niostudy;
import java.io.IOException;
/**
* Created by Administrator on 2017/8/6.
*/
public class TimeServer {
public static void main(String[] args) throws IOException {
Integer port=8080;
new Thread(new MultiplexerTimerServer(port)).start();
}
}
TimeClient
package niostudy;
/**
* Created by Administrator on 2017/8/7.
*/
public class TimeClient {
public static void main(String[] args) {
Integer port=8080;
String host="127.0.0.1";
new Thread(new TimeClientHandle(host,port)).start();
}
}
package niostudy;
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 java.util.Set;
/**
* Created by Administrator on 2017/8/7.
*/
public class TimeClientHandle implements Runnable {
private String host;
private Integer port;
private Selector selector;
private SocketChannel socketChannel;
private volatile boolean stop;
public TimeClientHandle(String host, Integer port) {
this.host = host;
this.port = port;
try {
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public void run() {
try {
doConnext();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
while (!stop) {
try {
selector.select(1000);
Set<SelectionKey> selectionKeySets = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeySets.iterator();
SelectionKey selectionKey;
while (iterator.hasNext()) {
selectionKey = iterator.next();
iterator.remove();
try {
handleInput(selectionKey);
} catch (Exception e) {
if (selectionKey != null) {
selectionKey.cancel();
if (selectionKey.channel() != null) {
selectionKey.channel().close();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
private void handleInput(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()) {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
//如果是可连接状态
if (selectionKey.isConnectable()) {
//如果完成了连接
if (socketChannel.finishConnect()) {
socketChannel.register(selector, SelectionKey.OP_READ);
doWrite(socketChannel);
} else
System.exit(1);
}
if (selectionKey.isReadable()) {
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int readBytes = socketChannel.read(readBuffer);
if (readBytes > 0) {
readBuffer.flip();
byte[] bytes = new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = new String(bytes, "UTF-8");
System.out.println("收到来自服务端的数据" + body);
this.stop = true;
} else if (readBytes < 0) {
selectionKey.cancel();
socketChannel.close();
}else {
;//do dothing
}
}
}
}
/**
* 连接服务端
*/
private void doConnext() throws IOException {
//如果连接成功则注册
if (socketChannel.connect(new InetSocketAddress(host, port))) {
doWrite(socketChannel);
socketChannel.register(selector, SelectionKey.OP_READ);
} else {
socketChannel.register(selector, SelectionKey.OP_CONNECT);
}
}
private void doWrite(SocketChannel socketChannel) throws IOException {
String data = "你好服务器!";
byte[] req = data.getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(req.length);
byteBuffer.put(req);
byteBuffer.flip();
socketChannel.write(byteBuffer);
//
if (!byteBuffer.hasRemaining()) {
System.out.println("message has bean send");
}
}
}