服务端代码:
package com.zeng.nio.socketChannel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
public class ServerDemo {
public static void main(String[] args) {
try (
//1 创建服务端的ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
){
//2 绑定端口号
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
//3 设置serverSocketChannel为非阻塞式
serverSocketChannel.configureBlocking(false);
//4 创建selector
Selector selector = Selector.open();
//5 把serverSocketChannel注册到selector中管理,并关注 accept事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true){
//6 等待客户端连接
if(selector.select(5000)<=0){
System.out.println("等待客户端连接。。。");
continue;
}
//7 selector监听所有事件
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()){
System.out.println("发生事件的通道有 "+selectionKeys.size()+" 个");
SelectionKey selectionKey = iterator.next();
//7.1 处理accept事件
if(selectionKey.isAcceptable()){
System.out.println("有一个新的客户端连接请求");
//7.1.1 生成对应客户端的socketChannel
SocketChannel socketChannel = serverSocketChannel.accept();
//7.1.2 设置socketChannel为非阻塞式
socketChannel.configureBlocking(false);
//7.1.3 把socketChannel注册到selector中管理,并关注 read事件,且给一个1024字节的缓冲区
socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
//7.2 处理 read 事件
if(selectionKey.isReadable()){
System.out.println("发生了一个新的read 事件");
//7.2.1 获取 selectionKey 对应的通道
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
//7.2.2 获取通道对应的缓冲区
ByteBuffer byteBuffer= (ByteBuffer) selectionKey.attachment();
//7.2.3 把通道的数据写入到缓冲区中
int read = socketChannel.read(byteBuffer);
//7.2.4 后台显示
System.out.println("From客户端:"+new String(byteBuffer.array(),0,read));
// System.out.println("From客户端:"+new String(byteBuffer.array(),0,byteBuffer.position()));
//7.2.5 清空缓存区
byteBuffer.clear();
}
//7.3 移除已经处理过的selectionKey
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class ClientDemo {
public static void main(String[] args) {
try (
//1 创建 socketChannel
SocketChannel socketChannel = SocketChannel.open();
) {
//2 设置为非阻塞式
socketChannel.configureBlocking(false);
//3 连接地址
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 9999);
//4 连接
if(!socketChannel.connect(inetSocketAddress)){
while (!socketChannel.finishConnect()){
System.out.println("客户端不会阻塞,可以做其他工作");
}
}
//5 发送消息给服务端
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String str="";
while (!"bye".equals(str=bufferedReader.readLine())){
ByteBuffer byteBuffer = ByteBuffer.wrap(str.getBytes());
socketChannel.write(byteBuffer);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}