linux

linux socket5是否支持异步操作

小樊
81
2024-12-29 06:14:22
栏目: 智能运维

Linux的socket编程确实支持异步操作

在Linux中,可以使用select()poll()epoll()等系统调用来实现异步I/O。这些函数允许您监视多个文件描述符(包括套接字),以便在其中一个或多个文件描述符准备好进行I/O操作时通知您。这样,您可以在单个线程中处理多个网络连接,从而实现异步操作。

以下是一个简单的示例,说明如何使用select()实现异步socket操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>

#define BUF_SIZE 1024

int main() {
    int serv_sock, clnt_sock;
    struct sockaddr_in serv_addr, clnt_addr;
    socklen_t clnt_addr_size;
    fd_set readfds;
    int max_fd;
    char buf[BUF_SIZE];

    // 创建套接字
    if ((serv_sock = socket(PF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 配置服务器地址
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(8080);

    // 绑定套接字
    if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(serv_sock, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 初始化文件描述符集合
    FD_ZERO(&readfds);
    max_fd = serv_sock;

    // 将服务器套接字添加到文件描述符集合
    FD_SET(serv_sock, &readfds);

    while (1) {
        // 等待文件描述符集合中的事件
        if (select(max_fd + 1, &readfds, NULL, NULL, NULL) < 0) {
            perror("select");
            exit(EXIT_FAILURE);
        }

        // 检查服务器套接字是否准备好接受连接
        if (FD_ISSET(serv_sock, &readfds)) {
            clnt_addr_size = sizeof(clnt_addr);

            // 接受客户端连接
            if ((clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, (socklen_t *)&clnt_addr_size)) < 0) {
                perror("accept");
                exit(EXIT_FAILURE);
            }

            // 将客户端套接字添加到文件描述符集合
            FD_SET(clnt_sock, &readfds);
            max_fd = max(max_fd, clnt_sock);

            printf("Connected client IP: %s, port: %d\n", inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port));
        }

        // 检查客户端套接字是否准备好读取数据
        if (FD_ISSET(clnt_sock, &readfds)) {
            int str_len = read(clnt_sock, buf, BUF_SIZE);

            if (str_len <= 0) {
                printf("Client disconnected\n");
                FD_CLR(clnt_sock, &readfds);
                close(clnt_sock);
            } else {
                printf("Received message from client: %s\n", buf);
                send(clnt_sock, "Message received", strlen("Message received"), 0);
            }
        }
    }

    // 关闭套接字
    close(serv_sock);
    return 0;
}

这个示例中的服务器使用select()来监视客户端连接和客户端数据读取事件。当客户端连接或客户端发送数据时,服务器会相应地处理这些事件。这样,服务器可以在单个线程中处理多个客户端连接,实现异步操作。

0
看了该问题的人还看了