服务端
public class Server {
//源码注释:requested maximum length of the queue of incoming connections.
//BACK_LOG影响的accept队列大小
public static final int BACK_LOG = 1024;
public static void main(String[] args) throws Exception {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
//设置非阻塞
serverChannel.configureBlocking(false);
//绑定端口,在服务端监听
serverChannel.bind(new InetSocketAddress("127.0.0.1", 8888), BACK_LOG);
//serverChannel.socket().bind(new InetSocketAddress("127.0.0.1",8888), BACK_LOG);
//创建Selector对象
Selector selector = Selector.open();
//ServerSocketChannel注册到Selector
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
//循环等待客户端连接
for (; ; ) {
if (selector.select(1000) == 0) {
System.out.println("服务器等待了1秒,无连接");
continue;
}
//关注事件集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
//如果是OP_ACCEPT,有新的客户端连接
if (key.isAcceptable()) {
SocketChannel channel = serverChannel.accept();
System.out.println("连接成功,SocketChannel:" + channel.hashCode());
channel.configureBlocking(false);
//关联buffer
channel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
//获取buffer
ByteBuffer buffer = (ByteBuffer) key.attachment();
//把通道数据放入缓冲区
channel.read(buffer);
}
//移除Selection,因为多线程,要防止重复操作
iterator.remove();
}
}
}
}
客户端
public class Client {
public static void main(String[] args) throws IOException {
//打开一个网络通道
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
//连接服务器
if (!channel.connect(new InetSocketAddress("127.0.0.1", 8888))) {
while (!channel.finishConnect()) {
System.out.println("连接需要时间,不阻塞,边做其他工作");
}
}
String str = "你好,chen";
//NIO wrap 会自动根据你字节数创建相应大小的buffer
ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());
//把缓冲区数据放入通道
channel.write(buffer);
System.in.read();
}
}
结果