转载自 https://blog.csdn.net/howard2005/article/details/79367657
Server端:
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.bind(new InetSocketAddress(9999));
System.out.println("Waiting for client...");
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true) {
int select = selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while(iterator.hasNext()) {
SelectionKey sk = iterator.next();
handleKey(selector, sk);
iterator.remove();
}
}
}
private static void handleKey(Selector selector, SelectionKey sk) throws IOException {
if(sk.isAcceptable()) {
ServerSocketChannel ss = (ServerSocketChannel)sk.channel();
ss.configureBlocking(false);
SocketChannel sc = ss.accept();
sc.configureBlocking(false);
System.out.println("有客户端接入,负责处理该请求的线程id:" + Thread.currentThread().getId());
sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
// 判断当前事件是否为read事件
if (sk.isReadable()) {
// 获取客户端通道
SocketChannel sc = (SocketChannel) sk.channel();
// 设置客户端通道非阻塞模式
sc.configureBlocking(false);
// 创建字节缓冲区
ByteBuffer buffer = ByteBuffer.allocate(10);
// 读取通道数据存在字节缓冲区
sc.read(buffer);
// 输出服务器端读取的数据
System.out.println("服务器端读到了数据:" + new String(buffer.array()) + Thread.currentThread().getId());
// 去掉read事件
// sc.register(selector, SelectionKey.OP_WRITE);
sc.register(selector, sk.interestOps() & ~SelectionKey.OP_READ);
}
// 判断当前事件是否为write事件
if (sk.isWritable()) {
// 获取客户端通道
SocketChannel sc = (SocketChannel) sk.channel();
// 设置客户端通道非阻塞模式
sc.configureBlocking(false);
// 定义字节缓冲区存放了数据
ByteBuffer buffer = ByteBuffer.wrap("天长地久".getBytes("utf-8"));
// 将字节缓冲区数据写入通道
sc.write(buffer);
// 提示用户
System.out.println("服务器端写入了数据。" + Thread.currentThread().getId());
// 去掉write事件
sc.register(selector, sk.interestOps() & ~SelectionKey.OP_WRITE);
}
}
Client端:
public static void main(String[] args) throws Exception {
// 创建SocketChannel对象
SocketChannel sc = SocketChannel.open();
// 设置客户端通道非阻塞模式
sc.configureBlocking(false);
// 请求连接服务器
sc.connect(new InetSocketAddress("127.0.0.1", 9999));
// 确保客户端连接成功
if (!sc.isConnected()) {
sc.finishConnect();
}
// 提示用户
System.out.println("连接成功!");
// 定义字节缓冲区
ByteBuffer buffer1 = ByteBuffer.wrap("HelloWorld".getBytes());
// 将字节缓冲区数据写入通道
sc.write(buffer1);
// 提示用户
System.out.println("客户端写入了数据。");
// 定义字节缓冲区
ByteBuffer buffer2 = ByteBuffer.allocate(100);
// 读取通道数据存入字节缓冲区
sc.read(buffer2);
// 调用缓冲区反转方法
buffer2.flip();
// 输出字节缓冲区实际字节数
System.out.println("缓冲区字节数:" + buffer2.limit());
// 输出客户端读取的内容
System.out.println("客户端读取的内容:" + new String(buffer2.array(), "utf-8"));
// 让客户端持续工作
while (true);
}
网友评论