客户端可以注册一个回调函数到内核的事件系统上,当服务器的数据到达时,内核会自动唤醒并调用这个函数,通知应用程序数据已经就绪。demo
时间: 2024-09-07 18:04:37 浏览: 39
一个c++网络库,基于epoll.zip
在许多编程环境中,例如在Unix-like系统(如Linux)的网络编程中,客户端通常会使用像`epoll`、`select`或Windows的`IOCP`这样的内核级事件API。下面是一个简单的`epoll`示例(在C语言中),展示了如何注册回调:
```c
#include <sys/epoll.h>
#include <stdio.h>
#include <string.h>
int epoll_fd; // 存储epoll实例的文件描述符
void data_received(int fd) {
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read > 0) {
printf("Data received: %s\n", buffer);
} else if (bytes_read == 0) {
printf("Connection closed.\n");
} else {
perror("Error reading from socket");
}
}
// 创建epoll实例
void setup_epoll() {
epoll_fd = epoll_create1(0); // 创建一个新的epoll实例
if (epoll_fd < 0) {
perror("Failed to create epoll instance");
}
int server_fd = connect_to_server(); // 连接到服务器
if (server_fd < 0) {
perror("Failed to connect to server");
return;
}
// 将服务器socket加入epoll,并注册回调
struct epoll_event event;
event.events = EPOLLIN | EPOLLET; // 设置为读取事件且立即触发
event.data.fd = server_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) < 0) {
perror("Failed to add socket to epoll");
}
}
// 主循环中检测事件
void main_loop() {
while (true) {
struct epoll_event events[10]; // 事件数组
const int num_events = epoll_wait(epoll_fd, events, sizeof(events), -1); // 等待事件
for (int i = 0; i < num_events; i++) {
if (events[i].data.fd == server_fd && (events[i].events & EPOLLIN)) { // 如果是服务器连接有数据可用
data_received(server_fd);
}
}
}
}
```
在这个例子中,`setup_epoll`函数设置了回调函数`data_received`来处理服务器发送的数据。然后在`main_loop`里,通过`epoll_wait`定期检查是否有新的事件发生,如果有数据到达,就会调用回调函数。
阅读全文