代码:
package com.cs.cloud.test.testnio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
/**
*@Description NIO:同步非阻塞
*
* NIO三大核心部分:Channel(通道),Buffer(缓冲区),Selector(选择器)
*
* NIO是面向缓冲区,或者面向块编程的.数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动
* ,这就增加了处理过程中的灵活性,使用它可以提供非阻赛式的高伸缩性网络
*
* 模型:
* ===================
* = =
* ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←= socektServer = →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
* ↓ = = ↓
* ↓ =================== ↓
* ↓ ↓
* =============== ===============
* = = = =
* ←←←←←←←←←←←←←←←←← = Selector = →→→→→→→→→→→→→→→→→ ←←←←←←←←←←←←←←←←←= Selector =→→→→→→→→→→→→→→→→→
* ↓ = = ↓ ↓ = = ↓
* ↓ =============== ↓ ↓ =============== ↓
* ↓ ↓ ↓ ↓ ↓ ↓
* ↓ ↓ ↓ ↓ ↓ ↓
* ↓ ↓ ↓ ↓ ↓ ↓
* ========== ========== ========== ========== ========== ==========
* = Channel= = Channel= = Channel= = Channel= = Channel= = Channel=
* ========== ========== ========== ========== ========== ==========
* ↓ buffer ↓ buffer ↓ buffer ↓ ↓ ↓
* ↓ ↓ ↓ ↓ ↓ ↓
* ========== ========== ========== ========== ========== ==========
* = Client = = Client = = Client = = Client = = Client = = Client =
* ========== ========== ========== ========== ========== ==========
*
*
*
*@Author Mr.CongShuo
*@Date 2021/3/2 0002
*@Time 0:00
*/
public class SockerServer {
public static void main(String[] args) throws Exception{
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
Selector selector = Selector.open();
serverSocketChannel.socket().bind(new InetSocketAddress(6666));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true){
if (selector.select(1000) == 0){
System.out.println("没有会话");
continue;
}
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
if (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
if (selectionKey.isAcceptable()){
System.out.println("有人链接");
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
if (selectionKey.isReadable()){
SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
ByteBuffer byteBuffer = (ByteBuffer)selectionKey.attachment();
String byteBufferString = byteBufferToString(socketChannel, byteBuffer);
System.out.println(selectionKey +" 数据来了: " + byteBufferString);
}
}
//移除防止重复
iterator.remove();
}
}
public static String byteBufferToString(SocketChannel socketChannel,ByteBuffer byteBuffer){
StringBuffer stringBuffer = new StringBuffer();
try {
int read = socketChannel.read(byteBuffer);
while (read != -1) {
byteBuffer.flip();
CharBuffer charBuffer = CharBuffer.allocate(1024);
Charset charset = Charset.forName("GBK");
CharsetDecoder decoder = charset.newDecoder();
decoder.decode(byteBuffer, charBuffer, true);
charBuffer.flip();
while (charBuffer.hasRemaining()){
stringBuffer.append(charBuffer.get());
}
byteBuffer.clear();
break;
}
}catch (Exception e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
}
启动cmd开启客户端:
输入连接命令:
telnet 127.0.0.1 6666
打开会话
ctrl + ]
发送数据
send 数据