// 初始化 socket,建立 socket 与 channel 的绑定关系SocketChannel socketChannel = SocketChannel.open();// 初始化远程连接地址SocketAddress remote = new InetSocketAddress(this.host, port);// I/O 处理设置阻塞,这也是默认的方式,可不设置socketChannel.configureBlocking(true);// 建立连接socketChannel.connect(remote);
Socket socket = socketChannel.socket();
PrintWriter pw = getWriter(socketChannel.socket());BufferedReader br = getReader(socketChannel.socket());
package com.jason.network.mode.nio;import com.jason.network.constant.HttpConstant;import com.jason.network.util.HttpUtil;import java.io.*;import java.net.InetSocketAddress;import java.net.Socket;import java.net.SocketAddress;import java.nio.channels.SocketChannel;public class NioBlockingHttpClient {
private SocketChannel socketChannel;
private String host;
public static void main(String[] args) throws IOException {
for (String host: HttpConstant.HOSTS) {
NioBlockingHttpClient client = new NioBlockingHttpClient(host, HttpConstant.PORT);
client.request();
}
}
public NioBlockingHttpClient(String host, int port) throws IOException {
this.host = host;
socketChannel = SocketChannel.open();
socketChannel.socket().setSoTimeout(5000);
SocketAddress remote = new InetSocketAddress(this.host, port);
this.socketChannel.connect(remote);
}
public void request() throws IOException {
PrintWriter pw = getWriter(socketChannel.socket());
BufferedReader br = getReader(socketChannel.socket());
pw.write(HttpUtil.compositeRequest(host));
pw.flush();
String msg;
while ((msg = br.readLine()) != null){
System.out.println(msg);
}
}
private PrintWriter getWriter(Socket socket) throws IOException {
OutputStream out = socket.getOutputStream();
return new PrintWriter(out);
}
private BufferedReader getReader(Socket socket) throws IOException {
InputStream in = socket.getInputStream();
return new BufferedReader(new InputStreamReader(in));
}}
import java.nio.channels.Selector;...private static Selector selector;static {
try {
selector = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}}SocketChannel socketChannel = SocketChannel.open();SocketAddress remote = new InetSocketAddress(host, port);// 设置非阻塞模式socketChannel.configureBlocking(false);socketChannel.connect(remote);
socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
操作类型 |
值 |
描述 |
所属对象 |
|---|---|---|---|
|
OP_READ |
1 << 0 |
读操作 |
SocketChannel |
|
OP_WRITE |
1 << 2 |
写操作 |
SocketChannel |
|
OP_CONNECT |
1 << 3 |
连接socket操作 |
SocketChannel |
|
OP_ACCEPT |
1 << 4 |
接受socket操作 |
ServerSocketChannel |
public void select() throws IOException {
// 获取就绪的 socket 个数
while (selector.select() > 0){
// 获取符合的 socket 在选择器中对应的事件句柄 key
Set keys = selector.selectedKeys();
// 遍历所有的key
Iterator it = keys.iterator();
while (it.hasNext()){
// 获取对应的 key,并从已选择的集合中移除
SelectionKey key = (SelectionKey)it.next();
it.remove();
if (key.isConnectable()){
// 进行连接操作
connect(key);
}
else if (key.isWritable()){
// 进行写操作
write(key);
}
else if (key.isReadable()){
// 进行读操作
receive(key);
}
}
}}// SelectionKey 代表 SocketChannel 在选择器中注册的事件句柄private void connect(SelectionKey key) throws IOException {
// 获取事件句柄对应的 SocketChannel
SocketChannel channel = (SocketChannel) key.channel();
// 真正的完成 socket 连接
channel.finishConnect();
// 打印连接信息
InetSocketAddress remote = (InetSocketAddress) channel.socket().getRemoteSocketAddress();
String host = remote.getHostName();
int port = remote.getPort();
System.out.println(String.format("访问地址: %s:%s 连接成功!", host, port));}// 字符集处理类private Charset charset = Charset.forName("utf8");private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
InetSocketAddress remote = (InetSocketAddress) channel.socket().getRemoteSocketAddress();
String host = remote.getHostName();
// 获取 HTTP 请求,同上一篇
String request = HttpUtil.compositeRequest(host);
// 向 SocketChannel 写入事件
channel.write(charset.encode(request));
// 修改 SocketChannel 所关心的事件
key.interestOps(SelectionKey.OP_READ);}private void receive(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
buffer.flip();
String receiveData = charset.decode(buffer).toString();
// 当再没有数据可读时,取消在选择器中的关联,并关闭 socket 连接
if ("".equals(receiveData)) {
key.cancel();
channel.close();
return;
}
System.out.println(receiveData);}
package com.jason.network.mode.nio;import com.jason.network.constant.HttpConstant;import com.jason.network.util.HttpUtil;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Iterator;import java.util.Set;public class NioNonBlockingHttpClient {
private static Selector selector;
private Charset charset = Charset.forName("utf8");
static {
try {
selector = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
NioNonBlockingHttpClient client = new NioNonBlockingHttpClient();
for (String host: HttpConstant.HOSTS) {
client.request(host, HttpConstant.PORT);
}
client.select();
}
public void request(String host, int port) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.socket().setSoTimeout(5000);
SocketAddress remote = new InetSocketAddress(host, port);
socketChannel.configureBlocking(false);
socketChannel.connect(remote);
socketChannel.register(selector,
SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
public void select() throws IOException {
while (selector.select(500) > 0){
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext()){
SelectionKey key = (SelectionKey)it.next();
it.remove();
if (key.isConnectable()){
connect(key);
}
else if (key.isWritable()){
write(key);
}
else if (key.isReadable()){
receive(key);
}
}
}
}
private void connect(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
channel.finishConnect();
InetSocketAddress remote = (InetSocketAddress) channel.socket().getRemoteSocketAddress();
String host = remote.getHostName();
int port = remote.getPort();
System.out.println(String.format("访问地址: %s:%s 连接成功!", host, port));
}
private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
InetSocketAddress remote = (InetSocketAddress) channel.socket().getRemoteSocketAddress();
String host = remote.getHostName();
String request = HttpUtil.compositeRequest(host);
System.out.println(request);
channel.write(charset.encode(request));
key.interestOps(SelectionKey.OP_READ);
}
private void receive(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
buffer.flip();
String receiveData = charset.decode(buffer).toString();
if ("".equals(receiveData)) {
key.cancel();
channel.close();
return;
}
System.out.println(receiveData);
}}
public static void main(String[] args) {
基于线程池的伪异步NIO模型 a = new 基于线程池的伪异步NIO模型();
a.startServer();}private Charset charset = Charset.forName("utf8");class WriteThread implements Runnable {
private SelectionKey key;
public WriteThread(SelectionKey key) {
this.key = key;
}
@Override public void run() {
SocketChannel socketChannel = (SocketChannel) key.channel();
Socket socket = socketChannel.socket();
try {
socketChannel.finishConnect();
} catch (IOException e) {
e.printStackTrace();
}
InetSocketAddress remote = (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();
String host = remote.getHostName();
int port = remote.getPort();
System.out.println(String.format("访问地址: %s:%s 连接成功!", host, port));
}}class ReadThread implements Runnable {
private SelectionKey key;
public ReadThread(SelectionKey key) {
this.key = key;
}
@Override public void run() {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
socketChannel.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
buffer.flip();
String receiveData = null;
try {
receiveData = new String(buffer.array(), "utf8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if ("".equals(receiveData)) {
key.cancel();
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
System.out.println(receiveData);
}}class ConnectThread implements Runnable {
private SelectionKey key;
public ConnectThread(SelectionKey key) {
this.key = key;
}
@Override public void run() {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = charset.encode("hello world");
try {
socketChannel.write(byteBuffer);
System.out.println("hello world");
} catch (IOException e) {
e.printStackTrace();
}
key.interestOps(SelectionKey.OP_READ);
}}public void startServer() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
SocketChannel socketChannel = SocketChannel.open();
Selector selector = Selector.open();
socketChannel.configureBlocking(false);
InetSocketAddress inetAddress = new InetSocketAddress(1234);
socketChannel.connect(inetAddress);
socketChannel.register(selector, SelectionKey.OP_CONNECT |
SelectionKey.OP_READ |
SelectionKey.OP_WRITE);
while (selector.select(500) > 0) {
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
if (key.isConnectable()) {
executorService.submit(new ConnectThread(key));
}else if(key.isReadable()) {
executorService.submit(new ReadThread(key));
}else {
executorService.submit(new WriteThread(key));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}}class NioNonBlockingHttpServer {
private static Selector selector;
private Charset charset = Charset.forName("utf8");
static {
try {
selector = Selector.open();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
NioNonBlockingHttpServer httpServer = new NioNonBlockingHttpServer();
httpServer.select();
}
public void request(int port) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().setSoTimeout(5000);
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(8383));// serverSocketChannel.register(selector,// SelectionKey.OP_CONNECT// | SelectionKey.OP_READ// | SelectionKey.OP_WRITE);
}
public void select() throws IOException {
while (selector.select(500) > 0) {
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
if (key.isAcceptable()) {
accept(key);
} else if (key.isWritable()) {
write(key);
} else if (key.isReadable()) {
receive(key);
}
}
}
}
private void accept(SelectionKey key) throws IOException {
SocketChannel socketChannel;
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
socketChannel = channel.accept();//接受连接请求
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
InetSocketAddress local = (InetSocketAddress) channel.socket().getLocalSocketAddress();
String host = local.getHostName();
int port = local.getPort();
System.out.println(String.format("请求地址: %s:%s 接收成功!", host, port));
}
private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
InetSocketAddress local = (InetSocketAddress) channel.socket().getRemoteSocketAddress();
String host = local.getHostName();
String msg = "hello Client";
channel.write(charset.encode(msg));
System.out.println(msg);
key.interestOps(SelectionKey.OP_READ);
}
private void receive(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
buffer.flip();
String receiveData = charset.decode(buffer).toString();
if ("".equals(receiveData)) {
key.cancel();
channel.close();
return;
}
System.out.println(receiveData);
}}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69906029/viewspace-2654776/ ,如需转载,请注明出处,否则将追究法律责任。