1

我对 C 设计模式不是很熟悉,并且正在寻找以下问题的最佳解决方案。我想写一个基于 libpurple 的聊天客户端。

在运行程序时,我希望能够连接和断开多个即时消息帐户。connect 和 disconnect 调用应通过命令行传递,但等待使用 gets() 输入;没有解决方案,因为程序应该一直运行,从已连接的即时消息帐户中获取新消息。

4

2 回答 2

2

您可能希望使用poll(或select) 来处理事件。所以在建立连接之后,你有文件描述符,此外你还有标准输入,它还有一个来自操作系统的文件描述符(即 0),你可以将所有这些文件描述符传递给poll,它会在出现时通知你是任何文件描述符上的传入数据。示例代码:

/* fd1, fd2 are sockets */
while(1) {
    pollfd fds[3];
    int ret;

    fds[0].fd = fd1;
    fds[1].fd = fd2;
    fds[2].fd = STDIN_FILENO;
    fds[0].events = POLLIN;
    fds[1].events = POLLIN;
    fds[2].events = POLLIN;
    ret = poll(fds, 3, -1); /* poll() blocks, but you can set a timeout here */
    if(ret < 0) {
        perror("poll");
    }
    else if(ret == 0) {
        printf("timeout\n");
    }
    else {
        if(fds[0].revents & POLLIN) {
            /* incoming data from fd1 */
        }
        if(fds[0].revents & (POLLERR | POLLNVAL)) {
            /* error on fd1 */
        }
        if(fds[1].revents & POLLIN) {
            /* incoming data from fd2 */
        }
        if(fds[1].revents & (POLLERR | POLLNVAL)) {
            /* error on fd2 */
        }
        if(fds[2].revents & POLLIN) {
            /* incoming data from stdin */
            char buf[1024];
            int bytes_read = read(STDIN_FILENO, buf, 1024);
            /* handle input, which is stored in buf */
        }
    }
}

你没有提到操作系统。这适用于 POSIX(OS X、Linux、带有 mingw 的 Windows)。如果你需要使用 Win32 API,它看起来会有些不同,但原理是一样的。

于 2011-10-07T12:09:34.370 回答
0

查看选择(2)。我不太确定 libpurple 是如何工作的,但如果它允许通过文件描述符(如文件或套接字)进行通知,那么 select 是您的解决方案。

您也可以尝试使用 pthread_create(3) 创建一个单独的线程。这样它就可以阻止获取(或其他),而您的程序的其余部分则执行此操作。

于 2011-10-07T12:10:29.230 回答