用poll写一段代码
时间: 2023-12-17 20:13:13 浏览: 36
下面是一个简单的使用poll函数实现I/O多路复用的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>
#define MAX_EVENTS 10
#define BUF_SIZE 1024
int main(int argc, char *argv[]) {
int listen_fd, conn_fd;
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len;
char buf[BUF_SIZE];
struct pollfd fds[MAX_EVENTS];
int nfds, i, n;
// 创建监听socket
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置地址重用选项
int reuse = 1;
if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// 绑定地址和端口号
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(8888);
if (bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(listen_fd, 10) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 初始化pollfd结构体数组
nfds = 1;
fds[0].fd = listen_fd;
fds[0].events = POLLIN;
// 循环等待事件发生
while (1) {
n = poll(fds, nfds, -1);
if (n < 0) {
perror("poll");
exit(EXIT_FAILURE);
}
// 处理就绪的文件描述符
for (i = 0; i < nfds; i++) {
if (fds[i].revents & POLLIN) {
if (fds[i].fd == listen_fd) {
// 有新的客户端连接
cli_len = sizeof(cli_addr);
conn_fd = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_len);
if (conn_fd < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("New client connected: %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
// 将新的客户端连接添加到pollfd数组中
if (nfds >= MAX_EVENTS) {
fprintf(stderr, "too many clients\n");
close(conn_fd);
continue;
}
fds[nfds].fd = conn_fd;
fds[nfds].events = POLLIN;
nfds++;
} else {
// 有数据可读
n = read(fds[i].fd, buf, BUF_SIZE);
if (n < 0) {
perror("read");
exit(EXIT_FAILURE);
} else if (n == 0) {
// 客户端关闭了连接
printf("Client disconnected\n");
close(fds[i].fd);
nfds--;
fds[i] = fds[nfds];
i--;
} else {
// 将数据回显给客户端
write(fds[i].fd, buf, n);
}
}
}
}
}
return 0;
}
```
该示例代码使用poll函数实现了一个简单的TCP回显服务器,可以处理多个客户端的连接和数据读写请求。在程序中,我们首先创建一个监听socket,然后将其添加到pollfd数组中,并设置POLLIN事件。每次调用poll函数等待事件发生时,如果有新的客户端连接,我们就在pollfd数组中添加一个新的文件描述符,并设置POLLIN事件;如果有客户端发送数据,我们就读取数据并将其回显给客户端;如果客户端关闭了连接,则从pollfd数组中删除该文件描述符。