NIOServer:
package com.mp.thread
import java.net.InetSocketAddress
import java.nio.ByteBuffer
import java.nio.channels.{SelectionKey, Selector, ServerSocketChannel, SocketChannel}
object NioServer08 {
def main(args: Array[String]): Unit = {
val server = new NioServer08(8888)
server.init
server.run()
}
}
class NioServer08(port:Int) extends Runnable{
// 初始化多路复用器
private var selector:Selector = _
// 初始化读写缓存
private var readBuffer:ByteBuffer = ByteBuffer.allocate(1024)
private var writeByffer: ByteBuffer = ByteBuffer.allocate(1024)
def init: Unit = {
println("初始化服务器")
selector = Selector.open()
// 开启服务器通道
val serverSocketChannel = ServerSocketChannel.open()
serverSocketChannel.bind(new InetSocketAddress(port))
// 设置非阻塞
serverSocketChannel.configureBlocking(false)
// 设置并标记服务状态
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT)
println("服务器启动了....")
}
override def run(): Unit = {
while (true) {
// 阻塞方法,当至少有一个通道被选中,才能返回
selector.select
// 返回已选择的通道标记集合,集合中保存的是通道的标记,相当于通道的id
val keys = selector.selectedKeys().iterator()
while (keys.hasNext){
val key = keys.next()
// 移除处理过的key
keys.remove()
if(key.isAcceptable){
acceptHandle(key)
}else if (key.isReadable){
readHandle(key)
}else if (key.isWritable) {
writeHandle(key)
}
}
}
}
def acceptHandle(key: SelectionKey): Unit = {
// 获取服务器通道
val serverChannel = key.channel().asInstanceOf[ServerSocketChannel]
// 阻塞方法,等待客户端连接
val channel = serverChannel.accept()
// 设置非阻塞
channel.configureBlocking(false)
println("有客户端连接进来了...")
// 设置对应客户端的通道标记状态,此通道为读取数据使用
channel.register(selector,SelectionKey.OP_READ)
}
def readHandle(key: SelectionKey): Unit = {
// 获取通道
val channel = key.channel().asInstanceOf[SocketChannel]
// 设置非阻塞
channel.configureBlocking(false)
// 清空缓存
this.readBuffer.clear()
val len = channel.read(readBuffer) // 阻塞方法,等待缓存中有数据
if (len == -1 ){
channel.close()
key.cancel()
}
this.readBuffer.flip() // 重置buffer游标,避免数据的不一致
val str = new String(readBuffer.array(),"UTF-8")
println("从客户端接收数据:"+ str)
}
def writeHandle(key: SelectionKey): Unit = {
}
}
NIO Client:
package com.mp.thread;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
/**
* ClassName: NioClient07
* Function: TODO
* Date: 2020-01-28 15:05
* author mapeng
* version V1.0
*/
public class NioClient07 {
public static void main(String[] args) {
try {
SocketChannel channel = SocketChannel.open();
// 连接远程服务器
channel.connect(new InetSocketAddress(8888));
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 设置非阻塞
channel.configureBlocking(false);
while (true){
System.out.println("请输入msg:");
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
// 将控制台数据写入到缓存
buffer.put(line.getBytes("UTF-8"));
buffer.flip();
// 发送服务器
channel.write(buffer);
buffer.clear();
/*int len = channel.read(buffer);
if(len == -1){
break;
}
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
System.out.println("接收客户端信息:" + new String(bytes,"UTF-8"));
buffer.clear();*/
}
} catch (IOException e) {
e.printStackTrace();
}
}
}