由于功能太过简单,就不过多阐述了,直接上阻塞式代码:
package com.lql.nio; import org.junit.Test; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; /**
* @author: lql
* @date: 2019.11.01
* Description: 客户端发送一条数据给服务端,服务端接收后反馈一条信息
*/
public class TestBlockingNIO2 { @Test
public void client() {
SocketChannel socketChannel = null;
FileChannel inChannel = null;
try {
//获取通道
socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8002));
inChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.READ); //获取缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while (inChannel.read(byteBuffer) != -1) {
byteBuffer.flip();
socketChannel.write(byteBuffer);
byteBuffer.clear();
} //切断
socketChannel.shutdownOutput(); //接收服务器端的反馈
int len = 0;
while ((len = socketChannel.read(byteBuffer)) != -1) {
byteBuffer.flip();
System.out.println(new String(byteBuffer.array(), 0, len));
byteBuffer.clear();
} } catch (IOException e) {
e.printStackTrace();
} finally {
if (inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socketChannel != null) {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} @Test
public void server() {
ServerSocketChannel serverSocketChannel = null;
FileChannel outChannel = null;
try {
serverSocketChannel = ServerSocketChannel.open();
outChannel = FileChannel.open(Paths.get("wy.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); SocketChannel socketChannel = serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8002)).accept();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (socketChannel.read(buffer) != -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
} //接收完发送反馈给客户端
buffer.put("服务器端接收客户端数据成功!!!".getBytes());
buffer.flip();
socketChannel.write(buffer); } catch (IOException e) {
e.printStackTrace();
} finally {
if (outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocketChannel != null) {
try {
serverSocketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }
}
接来下是非阻塞式的代码:
package com.lql.nio; import org.junit.Test; 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.time.LocalDateTime;
import java.util.Iterator; /**
* @author: lql
* @date: 2019.11.01
* Description: 非阻塞式(得有Channel,Buffer,Selector)
*/
public class TestNonBlockingNIO { //客户端
@Test
public void client() {
SocketChannel socketChannel = null;
try {
//获取通道
socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8006));
//切换成非阻塞模式
socketChannel.configureBlocking(false);
//获取缓冲区
ByteBuffer buf = ByteBuffer.allocate(1024);
//发送数据给服务端
buf.put(LocalDateTime.now().toString().getBytes());
buf.flip();
socketChannel.write(buf);
buf.clear();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socketChannel != null) {
try {
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} } @Test
public void Server() { ServerSocketChannel serverSocketChannel = null;
try {
serverSocketChannel = ServerSocketChannel.open();
//切换非阻塞模式
serverSocketChannel.configureBlocking(false);
//绑定并接收
serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8006));
//获取选择器
Selector selector = Selector.open();
//将通道注册到选择器上,指定监听“接收”事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //轮询式的获取选择器上已经“准备就绪”的事件
while (selector.select() > 0) {
//获取所有监听的事件
Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) {
//获取准备就绪的事件
SelectionKey key = it.next(); //判断具体是什么事件准备就绪
if (key.isAcceptable()) {
//获取客户端链接
SocketChannel socketChannel = serverSocketChannel.accept(); //客户端通道切换成非阻塞
socketChannel.configureBlocking(false); //将该通道注册要选择器上
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
//获取读就绪状态的通道
SocketChannel socketChannel = (SocketChannel) key.channel(); //读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = 0;
while ((len = socketChannel.read(buffer)) != -1) {
buffer.flip(); System.out.println(new String(buffer.array(), 0, len));
buffer.clear();
} }
//取消选择键
it.remove();
} } } catch (IOException e) {
e.printStackTrace();
} finally { } } }