//Socket服务器端
public class NIOServer03 {
public static void main(String[] args) throws IOException {
//创建选择器(多路复用器)对象
Selector selector = Selector.open();
//创建Socket服务端通道对象
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//配置为非阻塞
serverSocketChannel.configureBlocking(false);
//将Socket服务端通道的对象注册到选择器上,并指定其通道对象的注册事件为接收事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//指定Socket服务端的IP地址和端口
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
//绑定地址
serverSocketChannel.bind(address);
//服务端需要一直建立连接保存与客户端通讯,所以这里设为死循环
while(true){
//开启选择器进行监听,这里至少选择一个通道,如果该选择器是关闭抛出ClosedSelectorException
selector.select();
//返回此选择器的选定键集(注册的事件)。如果该选择器是关闭抛出ClosedSelectorException
Set<SelectionKey> selectionKeys = selector.selectedKeys();
//用迭代器遍历选定键集
Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
//如果key的注册事件为接收事件时执行
if(key.isAcceptable()){
//返回为其创建此密钥(key)的通道
ServerSocketChannel socketChannelByKey = (ServerSocketChannel) key.channel();
/**
* 接收与此通道的套接字建立的连接
* 如果没有挂起的连接,会立即返回null,否则它将无限期阻塞,直到有新连接或发生I/O错误
* 返回新连接的套接字通道
*/
SocketChannel socketChannel = socketChannelByKey.accept();
//设为非阻塞
socketChannel.configureBlocking(false);
//将该套接字通道注册为读取事件
socketChannel.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){ //如果key的注册事件为读取事件时执行
//返回为其创建此密钥(key)的通道
SocketChannel socketChannel = (SocketChannel) key.channel();
//解析读取该通道上的数据并返回打印
String data = readDataFromSocketChannel(socketChannel);
System.out.println("return data:"+data);
//关闭该套接字通道
socketChannel.close();
}
//没有其他注册事件则移除该key键
keyIterator.remove();
}
}
}
private static String readDataFromSocketChannel(SocketChannel socketChannel) throws IOException {
StringBuilder data=new StringBuilder();
//分配一个新的字节缓冲区,新缓冲区的位置将为零,它的限制将是它的容量,即1024(B),如果容量为负整数则抛出IllegalArgumentException
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while(true){ //循环读取数据
//清空缓冲区
//byteBuffer.clear();
//将Socket通道中数据读入字节缓冲区中
int read = socketChannel.read(byteBuffer);
if(read == -1){
//缓冲区不存在数据时停止循环
break;
}
//翻转这个缓冲区.限制设置为当前位置
byteBuffer.flip();
//返回此缓冲区的限制
int limit = byteBuffer.limit();
//设置字符数组,存储读取的数据
char[] dst=new char[limit];
for (int i = 0; i < limit; i++) {
//获取读取的数据
dst[i]= (char) byteBuffer.get(i);
}
//存入StringBuilder对象中
data.append(dst);
//byteBuffer.clear();
}
return data.toString();
}
}
//Socket客户端
public class NIOClient03 {
public static void main(String[] args) throws IOException {
//根据IP地址与端口与Socket服务器建立连接
Socket socket=new Socket("127.0.0.1",8888);
//获取socket中输出流并写入
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello world".getBytes());
//关闭输出流
outputStream.close();
}
}
执行结果: