SocketChannel用Selector和ThreadPoolExecutor做服务端
时间: 2023-08-13 13:11:28 浏览: 101
LikeShareServer
可以使用`SocketChannel`结合`Selector`和`ThreadPool`来实现服务端。下面是一个简单的示例代码:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private ExecutorService executorService;
private static final int BUFFER_SIZE = 1024;
public static void main(String[] args) throws IOException {
Server server = new Server();
server.start(8080);
}
public void start(int port) throws IOException {
// 创建Selector
selector = Selector.open();
// 创建ServerSocketChannel并绑定端口
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(port));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 创建线程池
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// 事件循环
while (true) {
// 阻塞等待就绪的事件
selector.select();
// 获取就绪的SelectionKey集合
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
// 处理事件
if (key.isAcceptable()) {
handleAcceptable(key);
} else if (key.isReadable()) {
handleReadable(key);
}
}
}
}
private void handleAcceptable(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println("New client connected: " + clientChannel.getRemoteAddress());
}
private void handleReadable(SelectionKey key) {
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
try {
int bytesRead = clientChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
String message = new String(data).trim();
System.out.println("Received message from client: " + message);
// 在线程池中处理业务逻辑
executorService.execute(() -> {
// 业务逻辑处理代码
// ...
// 响应客户端
ByteBuffer responseBuffer = ByteBuffer.wrap("Response from server".getBytes());
try {
clientChannel.write(responseBuffer);
} catch (IOException e) {
e.printStackTrace();
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
这个示例代码创建了一个基于`SocketChannel`的服务端,使用`Selector`来实现异步的事件处理,使用`ThreadPoolExecutor`来处理业务逻辑。客户端连接的接收和读取操作在`handleAcceptable`和`handleReadable`方法中处理。读取到客户端消息后,会将业务逻辑交给线程池处理,并响应客户端。你可以根据自己的需要在业务逻辑处理代码中添加具体的业务逻辑。
阅读全文