客户端与服务器连接流程图解 服务端代码:
```java
package com.yadong.netty.study;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;
public class NIOServer {
public static void main(String[] args) throws IOException {
//创建ServerSocketChannel -> ServerSocket
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//绑定一个端口6666,在服务器端监听
serverSocketChannel.socket().bind(new InetSocketAddress(6666));
//设置为非阻塞
serverSocketChannel.configureBlocking(false);
//得到一个selector对象
Selector selector = Selector.open();
//把serverSocketChannel 注册到 selector 关心事件为OP_ACCEPT;
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//循环等待客户端连接
while(true){
//等待1s,如果没有事件发生(连接),返回
if(selector.select(1000) == 0){ //没有事件发生
System.out.println("服务器等待了1秒,无连接");
continue;
}
//如果返回的>0 就获取到相关的selectionKey集合
//1.如果返回的>0,表示已经获取到关注的事件
//2.selector.selectedKeys() 返回关注事件的集合
//通过selectionKeys反向获取通道
Set<SelectionKey> selectionKeys = selector.selectedKeys();
//遍历Set<SelectionKey>, 使用迭代器遍历
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while(iterator.hasNext()){
//获取到SelectionKey
SelectionKey key = iterator.next();
if(key.isAcceptable()){
//给该客户端生成一个SocketChannel
SocketChannel socketChannel = serverSocketChannel.accept();
//将socketChannel设置为非阻塞
socketChannel.configureBlocking(false);
System.out.println("connect successfully!");
//将socketChannel 注册到selector 关注事件为OP_READ, 同时给socketChannel关联一个Buffer
socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
if(key.isReadable()){ //发生OP_READ
//通过key 反向获取到对应channel
SocketChannel channel = (SocketChannel) key.channel();
//获取到该channel关联的buffer
ByteBuffer buffer = (ByteBuffer) key.attachment();
channel.read(buffer);
System.out.println("from 客户端"+new String(buffer.array()));
}
//手动从集合中移除当前的selectionKey
iterator.remove();
}
}
}
}
客户端代码:
package com.yadong.netty.study;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
public class NIOClient {
public static void main(String[] args) throws Exception{
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 6666);
if (!socketChannel.connect(inetSocketAddress)) {
while(!socketChannel.finishConnect()){
System.out.println("因为连接需要时间,客户端不会阻塞,可以做其他工作...");
}
}
String str = "hello 尚硅谷";
ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());
socketChannel.write(buffer);
System.in.read();
}
}
|