客户端参考:https://www.jianshu.com/p/027af54275f3
public static void main(String[] args) throws Exception {
// 打开一个多路io复用管理器
Selector selector = Selector.open();
// 打开一个tcp通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 设置非阻塞模式
serverSocketChannel.configureBlocking(false);
// 绑定监听本地ip端口
serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8080));
// 注册连接事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 此方法会阻塞直到有io准备好
selector.select();
// 获取key迭代器
Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();
// 如果有key
while (selectionKeyIterator.hasNext()) {
// 获取一个key
SelectionKey selectionKey = selectionKeyIterator.next();
// 删除获取到的key以免重复获取
selectionKeyIterator.remove();
// 如果是连接事件
if (selectionKey.isAcceptable()) {
// 获取和客户端连接的通道
ServerSocketChannel sc = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = sc.accept();
// 设置非阻塞模式
socketChannel.configureBlocking(false);
// 赋予读写通道的权限
socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
// 发一条数据给客户端
socketChannel.write(ByteBuffer.wrap("我是服务端发来的".getBytes()));
// 判断到可读的事件
} else if (selectionKey.isReadable()) {
// 得到此事件的socket通道
SocketChannel sc = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int i = sc.read(byteBuffer);
// -1表示客户端已关闭并且没有数据了
//正确做法是while(sc.read(byteBuffer)>0) 一直接收,demo就简单写了
if (i != -1) {
byte[] data = new byte[i];
byteBuffer.flip();
byteBuffer.get(data);
System.out.println("服务器收到消息: " + new String(data));
}
}
}
}
}
网友评论