NIO TCP 通信通过??ServerSocketChannel ,SocketChannel,Selector 来完成 ?
1.服务器端 ?
package com.nio.tcp;
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;
public class TCPNIOServer {
public static void main(String[] args) throws IOException {
System.out.println("服务端已经启动,在 8080 端口监听 ......");
ServerSocketChannel channel = ServerSocketChannel.open();// 打开服务通道
channel.configureBlocking(false);// 设置为非阻塞
channel.socket().bind(new InetSocketAddress(8080));// 绑定连接 和 监听端口
startListen(channel);
channel.close();
}
private static void startListen(ServerSocketChannel channel)??throws IOException {
Selector selector = Selector.open();// 打开选择器
channel.register(selector, SelectionKey.OP_ACCEPT);// 通道注册到选择器,监听接受事件
// 轮训 获取选择 已经准备就绪 的事件
while (selector.select() > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();// 获取当前选择器所有注册的已经就绪的监听事件
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()) {
doAcceptable(channel, selector);
} else if (selectionKey.isReadable()) {
doReadable(channel, selector, selectionKey);
} else if (selectionKey.isConnectable()) {
} else if (selectionKey.isWritable()) {
}
iterator.remove();
}
}
}
private static void doAcceptable(ServerSocketChannel channel, Selector selector) throws IOException {
SocketChannel socketChannel = channel.accept();// 接受就绪,获取客户端连接
if(socketChannel==null)
{
return;
}
socketChannel.configureBlocking(false);// 设置非阻塞
socketChannel.register(selector, SelectionKey.OP_READ);// 将通道注册到服务器上,监听读事件
}
private static void doReadable(ServerSocketChannel channel, Selector selector, SelectionKey selectionKey) throws IOException {
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();// 获取当前选择器状态的通道
// 分配缓冲区,读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = 0;
while ((len = socketChannel.read(buffer)) > 0) {
buffer.flip();
System.out.println(new String(buffer.array(), 0, len));
buffer.clear();
}
}
}
2.客户端 ?
package com.nio.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Scanner;
public class TCPNIOClient {
public static void main(String[] args) {
System.out.println("客户端已经启动...");
SocketChannel socketChannel=null;
try {
socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));//创建通道
socketChannel.configureBlocking(false);// 设置非阻塞
ByteBuffer buffer = ByteBuffer.allocate(1024);
String data="忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处。";
buffer.put(data.getBytes());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
} catch (IOException e) {
e.printStackTrace();
}
finally
{
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
测试运行结果:
首先启动 服务器端 TCPNIOServer 服务端已经启动,在 8080 端口监听 ......
忍耐和坚持虽是痛苦的事情,但却能渐渐地为你带来好处。
然后启动 客户端 TCPNIOClient
客户端已经启动...
图解: ?
|