nio.socket为非阻塞的,基本的类有ServerSocketChannel(类似于一个大容器),Selector(事件注册与分发器),ServerSocket(一个服务端),SocketChannel(通信通道),SelectionKey(注册号)
写了一个例子,一个服务端,一个客户端,服务端接收请求并将一个byte数组写入通道,客户端在通道中收到请求并打印出来
服务端:
public class ServerSocketChannelTest {
private static byte[] data = new byte[255];
public static void main(String[] args) throws IOException {
for (int i = 0; i < data.length; i++) {
data[i] = (byte) i;
}
//新建NIO通道
ServerSocketChannel server = ServerSocketChannel.open();
//使通道为非阻塞
server.configureBlocking(false);
//创建基于NIO通道的socket连接
ServerSocket ss = server.socket();
//新建socket通道的端口
ss.bind(new InetSocketAddress(9000));
//将NIO通道绑定到选择器
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
//获取通道内是否有选择器的关心事件
int num = selector.select();
//如果小于1,停止此次循环,进行下一个循环
if (num < 1) {
continue;
}
//获取通道内关心事件的集合
Set selectedKeys = selector.selectedKeys();
Iterator iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
//移走此次事件
iterator.remove();
if (key.isAcceptable()) {
//获取对应的SocketChannel
SocketChannel client = server.accept();
System.out.println("Accepted connection from " + client);
//使此通道为非阻塞
client.configureBlocking(false);
//将数组data的大小定义为ByteBuffer缓冲区的大小
ByteBuffer source = ByteBuffer.wrap(data);
//在此通道上注册事件
SelectionKey key2 = client.register(selector,
SelectionKey.OP_WRITE);
//通道执行事件
key2.attach(source);
} else if (key.isWritable()) {
//获取此通道的SocketChannel
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer output = (ByteBuffer) key.attachment();
//如果缓存区没了,重置一下
if (!output.hasRemaining()) {
output.rewind();
}
//在此通道内写东西
client.write(output);
}
key.channel().close();
}
}
}
}
客户端
public class SocketChannelTest {
public static void main(String[] args) throws Exception {
//建立到服务端的链接
SocketAddress address = new InetSocketAddress("127.0.0.1", 9000);
SocketChannel client = SocketChannel.open(address);
//创建静态的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(255);
//读取数据,到buffer中
client.read(buffer);
//将position重新置为0
buffer.clear();
//输出缓冲区的数据
for (int i = 0; i < buffer.array().length; i++) {
System.out.println(buffer.array()[i]);
}
}
}
直接运行下试试,没有错误的,我测试过了,注释都写在那里,会有助于你理解.