Server:
package com.colorcc.sample.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
public class NoneBlockServer {
public static void main(String[] args) throws IOException {
try (Selector selector = Selector.open()) {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress("127.0.0.1", 8096), 50);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel)key.channel();
SocketChannel channel = server.accept();
channel.configureBlocking(false);
System.out.println("Accept new client request: " + channel.socket().getRemoteSocketAddress().toString());
channel.register(selector, SelectionKey.OP_READ); // 监听服务器读数据请求
} else if (key.isReadable()) {
System.out.println("Read request data and do biz process.");
SocketChannel channel = (SocketChannel)key.channel();
String remote = channel.getRemoteAddress().toString();
StringBuffer content = new StringBuffer();
content.append("accept[" + remote + "]: ");
ByteBuffer buffer = ByteBuffer.allocate(8096);
while (true) {
buffer.clear();
int read = channel.read(buffer);
if (read > 0) {
buffer.flip(); // 设置 buffer 为读数据模式
CharBuffer cb = Charset.forName("UTF-8").decode(buffer);
content.append(cb.toString());
} else {
break;
}
}
System.out.println(content.toString());
System.out.println("do biz ...");
channel.register(selector, SelectionKey.OP_WRITE); // 监听服务器端写数据请求
} else if (key.isWritable()) {
System.out.println("Send response to request.");
SocketChannel channel = (SocketChannel)key.channel();
channel.write(ByteBuffer.wrap("no block server response".getBytes()));
channel.register(selector, SelectionKey.OP_READ); // 监听服务器端读数据请求
}
}
}
}
}
}
Client:
package com.colorcc.sample.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NoneBlockClient {
public static void main(String[] args) throws IOException {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 1; i++) {
executor.submit(new Runnable() {
@Override
public void run() {
try {
request();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
private static void request() throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8096));
if (socketChannel.finishConnect()) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10000; i++) {
sb.append("a" + i + ",");
}
socketChannel.write(ByteBuffer.wrap(sb.toString().getBytes()));
try {
Thread.sleep(1000); // 为了给服务器执行biz并返回response
} catch (InterruptedException e) {
e.printStackTrace();
}
ByteBuffer buffer = ByteBuffer.allocate(100);
socketChannel.socket().getChannel().read(buffer);
buffer.flip(); // 设置 buffer 为读数据模式
CharBuffer decode = Charset.forName("UTF-8").decode(buffer);
System.out.println("Get response from: " + decode.toString());
// socketChannel.socket().close();
}
// socketChannel.close();
}
}
Server:
Accept new client request: /127.0.0.1:35006
Read request data and do biz process.
accept[/127.0.0.1:35006]: a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,...,a9999,
do biz ...
Send response to request.
Client:
Get response from: no block server response
TCP/IP包:
遗留问题:
无关闭操作,处理关闭 action.