poll机制监听多个event

/**
 * @brief powermanagement process with file descriptor
 *
 */
static int powermanagement_process(void)
{
    const struct bagad_cli_cbs cbs = { powermanagement_notify_conn_status, powermanagement_handle_msg };
    struct bagad_cli *bagad_cli;
    //TODO Unix SOCKET
/*    struct sockaddr sa_addr = {0};
    struct sockaddr_in *addr_in;*/
    struct user_data userdata;
    struct pollfd fds[3] = {0};
    struct itimerspec nval;
    int fd_timer = -1;
    int ret;

    powermanagement_log_time("process");
    ULOGW("powermanagement process");

    signal(SIGINT, &sig_handler);
    signal(SIGTERM, &sig_handler);

    sys_prop_set(PROP_PWCONTROL_BOOTCOMPLETED, "0");
    sys_prop_set(PROP_BACKLIGHT_READY, "0");
    sys_prop_set(PROP_GMSL2_SERIALIZER_READY, "0");
    sys_prop_set(PROP_BYPARTLABEL_LINK_READY, "0");
    sys_prop_set(PROP_TOUCH_INPUT_READY, "0");

    //TODO Unix SOCKET
/*    addr_in = (struct sockaddr_in *)&sa_addr;
    addr_in->sin_family = AF_INET;
    addr_in->sin_addr.s_addr = inet_addr(LOCAL_IP);
    addr_in->sin_port = htons(LOCAL_PORT);
*/
    //TODO Unix SOCKET
/*    bagad_cli = bagad_cli_new(NULL, &cbs, &sa_addr, sizeof(sa_addr), &userdata);
*/
    bagad_cli = bagad_cli_new(NULL, &cbs, NULL, 0, &userdata);
    userdata.bagad_cli = bagad_cli;
    ULOGD("bagad_cli_new: %p", bagad_cli);

    ret = pipe(fd_pipes);
    fds[0].fd = fd_pipes[0];
    fds[0].events = POLLIN;
    ULOGD("pipe fd: %d", fds[0].fd);

    fds[1].fd = bagad_cli_get_fd(bagad_cli);
    fds[1].events = POLLIN;
    ULOGD("bagad_cli_get_fd: %d", fds[0].fd);

    fd_timer = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
    nval.it_value.tv_sec  = 0;
    nval.it_value.tv_nsec = 50000000; //50ms
    nval.it_interval.tv_sec  = nval.it_value.tv_sec;
    nval.it_interval.tv_nsec = nval.it_value.tv_nsec;
    ret = timerfd_settime(fd_timer, 0, &nval, NULL);
    fds[2].fd = fd_timer;
    fds[2].events = POLLIN;
    ULOGD("timer fd: %d", fds[2].fd);

    bypartlabel_link_load_config();

    for (;;)
    {
        do
        {
            ret = poll(fds, sizeof(fds) / sizeof(fds[0]), -1);
        }
        while (ret < 0 && errno == EINTR);

        if (ret < 0)
        {
            ULOGE("poll error=%d(%s)", errno, strerror(errno));
            for (uint16_t i=0; i<(sizeof(fds) / sizeof(fds[0])); i++)
            {
                ULOGD("poll fds %d, revents %i", i, fds[i].revents);
            }
        }

        // signal fd
        if (fds[0].revents != 0)
        {
            ULOGD("signal poll revents %d, exit", fds[0].revents);
            break;
        }

        // bagad fd
        if (fds[1].revents != 0)
        {
            ULOGD("bagad poll revents %d", fds[1].revents);
            bagad_cli_process_fd(bagad_cli);
        }

        // timer fd
        if (fds[2].revents != 0)
        {
            //TODO debug: ULOGD("timer poll revents %d", fds[2].revents);

            ret = timer_process_fd(fds[2].fd);
            if (ret == 0)
            {
                ULOGD("timer all ready, stop timer");
                close(fd_timer);
                fds[2].fd = -1;
                fd_timer = -1;
            }
        }
        process_all();
    }

    close(fd_pipes[0]);
    close(fd_pipes[1]);
    bagad_cli_destroy(bagad_cli);
    if (fd_timer != -1) close(fd_timer);
    ULOGW("powermanagement exiting");
    return 0;
}

 

要使用`poll`实现TCP服务端的一对多连接,你可以按照以下步骤进行: 1. 创建一个TCP服务器套接字,并绑定到一个特定的IP地址和端口号上。 2. 使用`listen`函数开始监听传入的连接请求。 3. 创建一个`poll`对象,并将服务器套接字添加到该对象中。 4. 创建一个空的字典,用于存储客户端套接字和其对应的文件描述符。 5. 进入主循环,使用`poll`函数等待事件发生。 6. 当服务器套接字上有新的连接请求时,使用`accept`函数接受该连接,并将返回的客户端套接字添加到`poll`对象中。 7. 当有客户端套接字上有数据可读时,使用`recv`函数接收数据,并进行相应的处理。 8. 当有客户端套接字断开连接时,关闭该套接字,并从`poll`对象和字典中移除。 9. 回到第5步,继续等待事件发生。 下面是一个简单的示例代码,演示了如何使用`poll`实现TCP服务端的一对多连接: ```python import socket import select server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 12345)) server_socket.listen(5) poll = select.poll() poll.register(server_socket.fileno(), select.POLLIN) clients = {} while True: events = poll.poll() for fileno, event in events: if fileno == server_socket.fileno(): # 有新的连接请求 client_socket, addr = server_socket.accept() poll.register(client_socket.fileno(), select.POLLIN) clients[client_socket.fileno()] = client_socket elif event & select.POLLIN: # 有数据可读 client_socket = clients[fileno] data = client_socket.recv(1024) if data: # 处理接收到的数据 # ... else: # 客户端断开连接 client_socket.close() poll.unregister(fileno) del clients[fileno] ``` 在这个示例中,我们使用了`socket`模块来创建套接字,使用`select`模块来进行事件的监听。通过`poll`对象的`register`方法,我们可以将文件描述符和相应的事件类型注册到`poll`对象中。然后,通过调用`poll`对象的`poll`方法,我们可以等待事件发生,并返回发生事件的文件描述符和事件类型。根据这些信息,我们可以实现相应的逻辑来处理连接、接收数据和断开连接等操作。 请注意,这只是一个简单的示例,你还可以根据自己的需求进行适当的修改和扩展。另外,需要注意处理异常情况和错误处理,以保证程序的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值