原理
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.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
public class BlockServer {
public static void main(String[] args) throws IOException {
try (Selector selector = Selector.open()) {
// step 1: 打开socket
ServerSocketChannel serverChannel = ServerSocketChannel.open();
// step 2: 绑定到 ip 和 端口
serverChannel.bind(new InetSocketAddress(8012), 200);
// step 3: 设置为 block
serverChannel.configureBlocking(<strong><em>true</em></strong>);
while (true) {
// step 4: 接收一个客户端请求,如果没有请求,则 block 等待
SocketChannel socket = serverChannel.accept();
// step 5: server接收到请求后,通过 channel 读入到 buffer 中
ByteBuffer bb = ByteBuffer.allocate(20);
socket.read(bb);
<strong>bb.flip(); // 设置 buffer 为读数据模式</strong>
String remote = socket.getRemoteAddress().toString();
CharBuffer decode = Charset.forName("UTF-8").decode(bb);
System.out.println("accept[" + remote + "]: " + decode.toString());
// step 6: 根据请求数据,处理具体的业务逻辑
System.out.println("do biz[" + remote + "] ...");
// step 7: 將 response 返回給客戶端. 通過將數據寫入socket的緩存實現
String resp = "server response[" + remote + "]";
socket.write(ByteBuffer.wrap(resp.getBytes()));
System.out.println("send: " + resp);
socket.close();
}
}
}
}
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.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
public class BlockClient {
public static void main(String[] args) throws IOException {
request();
}
private static void request() throws IOException, CharacterCodingException {
// step 1: 打開一個 socket
SocketChannel socketChannel = SocketChannel.open();
// step 2: 請求連接到服務器
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8012));
if (socketChannel.finishConnect()) {
// step 3: 連接成功後,法請求。
ByteBuffer bb = ByteBuffer.allocate(100);
socketChannel.write(ByteBuffer.wrap("Hello".getBytes()));
// step 4: block等待服務端的 response.
socketChannel.read(bb);
bb.flip();
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
CharBuffer cb = decoder.decode(bb);
System.out.println("client resp: " + cb);
}
}
}