tcp_server_poll函数
时间: 2023-10-11 19:10:56 浏览: 128
`tcp_server_poll()` 函数通常用于在 TCP 服务器中处理客户端连接。它的作用是检查当前有没有待处理的客户端连接请求或者已经建立连接的客户端是否有数据待处理。它可以通过使用 `select()` 或者 `poll()` 系统调用来实现。下面是一个使用 `poll()` 的例子:
```c
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#define MAX_CLIENTS 10
#define BUFFER_SIZE 4096
int main(int argc, char *argv[]) {
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建 TCP socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置 socket 地址可重用
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
// 绑定 socket 地址
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听客户端连接
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
struct pollfd clients[MAX_CLIENTS];
clients[0].fd = server_fd;
clients[0].events = POLLIN;
int n_clients = 1;
while (1) {
// 等待客户端连接或者数据到达
int activity = poll(clients, n_clients, -1);
if (activity < 0) {
perror("poll failed");
exit(EXIT_FAILURE);
}
// 处理新的客户端连接请求
if (clients[0].revents & POLLIN) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("New client connected\n");
if (n_clients == MAX_CLIENTS) {
printf("Too many clients\n");
close(new_socket);
} else {
clients[n_clients].fd = new_socket;
clients[n_clients].events = POLLIN;
n_clients++;
}
}
// 处理已经建立连接的客户端发送的数据
for (int i = 1; i < n_clients; i++) {
if (clients[i].revents & POLLIN) {
valread = read(clients[i].fd, buffer, BUFFER_SIZE);
if (valread == 0) {
// 客户端关闭连接
close(clients[i].fd);
printf("Client disconnected\n");
clients[i] = clients[n_clients-1];
n_clients--;
} else {
// 处理客户端发送的数据
printf("%s\n", buffer);
send(clients[i].fd, buffer, strlen(buffer), 0);
memset(buffer, 0, BUFFER_SIZE);
}
}
}
}
return 0;
}
```
在 `main()` 函数中,首先创建一个 TCP socket,并设置 socket 地址可重用。然后,绑定 socket 地址,并开始监听客户端连接。
接下来,创建一个 `pollfd` 数组,用于存储所有的客户端 socket 描述符。将 `server_fd` 添加到数组中,并设置 `POLLIN` 事件,这样当有新的客户端连接请求到达时,就会触发 `POLLIN` 事件。
在 `while` 循环中,调用 `poll()` 等待客户端连接或者数据到达。如果 `POLLIN` 事件触发并且是来自 `server_fd` 的,说明有新的客户端连接请求到达,需要调用 `accept()` 来接受连接,并将新的客户端 socket 描述符添加到 `pollfd` 数组中。如果已经达到了最大客户端数,就需要关闭新的连接。如果是已经建立连接的客户端有数据到达,就需要读取数据,处理数据,并将响应数据发送回客户端。如果客户端关闭了连接,需要将其从 `pollfd` 数组中删除。
需要注意的是,`poll()` 函数的最后一个参数表示超时时间。如果设置为 -1,则表示一直等待直到有事件触发;如果设置为 0,则表示立即返回,不等待事件。如果设置为一个正整数,则表示等待指定的毫秒数后返回。
阅读全文