java写一个异步的tcp服务器
时间: 2024-03-12 12:44:23 浏览: 19
下面是一个简单的Java异步TCP服务器的示例代码:
```java
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class AsyncTCPServer {
private final static int BUFFER_SIZE = 1024;
public static void main(String[] args) {
try {
// 创建ServerSocketChannel对象,监听指定端口
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8888));
serverSocketChannel.configureBlocking(false);
// 创建Selector对象
Selector selector = Selector.open();
// 注册ServerSocketChannel到Selector,监听ACCEPT事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started.");
// 进入死循环,等待事件发生
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
// 处理ACCEPT事件
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Client connected: " + socketChannel.getRemoteAddress());
} else if (key.isReadable()) {
// 处理READ事件
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
int numBytes = socketChannel.read(buffer);
if (numBytes == -1) {
// 客户端关闭连接
key.cancel();
socketChannel.close();
System.out.println("Connection closed: " + socketChannel.getRemoteAddress());
} else {
// 读取数据并处理
buffer.flip();
byte[] bytes = new byte[numBytes];
buffer.get(bytes);
String message = new String(bytes);
System.out.println("Received message from client: " + message);
// 发送响应给客户端
socketChannel.register(selector, SelectionKey.OP_WRITE, ByteBuffer.wrap("Hello from server!".getBytes()));
}
} else if (key.isWritable()) {
// 处理WRITE事件
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = (ByteBuffer) key.attachment();
socketChannel.write(buffer);
if (!buffer.hasRemaining()) {
key.interestOps(SelectionKey.OP_READ);
}
}
// 从selectedKeys集合中删除已处理的事件
selector.selectedKeys().remove(key);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
这个服务器使用了Java NIO的异步非阻塞模式,可以同时处理多个客户端连接。在启动服务器后,它会创建一个ServerSocketChannel对象,并注册到Selector中,监听ACCEPT事件。当一个客户端连接成功后,会创建一个SocketChannel对象,并注册到Selector中,监听READ事件。当客户端发送数据时,服务器会读取数据并处理,然后将响应消息注册到Selector中,监听WRITE事件。当可以写入数据时,服务器会将响应消息发送给客户端。
需要注意的是,在使用Java NIO进行网络编程时,需要手动管理缓冲区,而且事件处理的顺序不能保证,因此需要特别小心。