这个是服务端的代码
主要用selector进行事件驱动,当有连接事件的时候线程才会执行,线程不会一直运行浪费性能。并且实现对客户端发送数据,如果一次没有发送完毕可以多次发送避免一次发送占用太长的事件,因为发送网络数据跟网速以及相关的组件的大小限制,当网络那边不能及时发送的时候,这边就会等待他,导致这里占用CPU。所以可以分多次写入避免让cpu占空。
package com.cgm.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* @create: 2023-11-07 19:36
* @Description: xxxx
*/
public class WriteServer {
public static void main(String[] args) throws IOException {
//1.建立连接
ServerSocketChannel ssc = ServerSocketChannel.open();
//2.设置为非阻塞模式
ssc.configureBlocking(false);
//3.生成一个selector
Selector selector = Selector.open();
//4.把这个通道注册到selector里面并且设置的监听事件
SelectionKey selectionKey = ssc.register(selector,SelectionKey.OP_ACCEPT);
ssc.bind(new InetSocketAddress(8080));
while (true){
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
SelectionKey scKey = sc.register(selector, 0, null);
scKey.interestOps(SelectionKey.OP_READ);
//向客户端发送数据
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 5000000; i++) {
stringBuilder.append("a");
}
ByteBuffer byteBuffer = Charset.defaultCharset().encode(stringBuilder.toString());
int write = sc.write(byteBuffer);
System.out.println(write);
if (byteBuffer.hasRemaining()){
scKey.interestOps(scKey.interestOps()+SelectionKey.OP_WRITE);
scKey.attach(byteBuffer);
}
}else if (key.isWritable()){
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer attachment = (ByteBuffer) key.attachment();
int write = socketChannel.write(attachment);
System.out.println(write);
//当buffer为空就要把这个buffer挂载取消
if (!attachment.hasRemaining()){
key.attach(null);
//既然数据都写完了就不需要关注可写事件了
key.interestOps(key.interestOps()-SelectionKey.OP_WRITE);
}
}
}
}
}
}
下面主要就是客户端的代码,接受到服务端的数据,然后解析数据。
package com.cgm.nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
/**
* @create: 2023-11-07 19:54
* @Description: xxxx
*/
public class WriterClient {
public static void main(String[] args) throws IOException {
SocketChannel sc = SocketChannel.open();
sc.connect(new InetSocketAddress(8080));
int count=0;
while (true){
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
count+= sc.read(byteBuffer);
byteBuffer.clear();
System.out.println(count);
}
}
}