Лучшее решение для динамического подключения учетной записи в C?

Я не очень знаком с шаблонами проектирования C и ищу лучшее решение для следующей проблемы. Я хочу написать небольшой клиент чата на основе libpurple.

Во время работы программы я хочу иметь возможность подключать и отключать несколько учетных записей мгновенных сообщений. Вызовы connect и connect должны передаваться через командную строку, но ожидая ввода с помощью get (); не является решением, потому что программа должна запускаться все время, получая новые сообщения от уже подключенных учетных записей мгновенных сообщений.

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, Windows с mingw). Если вам нужно использовать Win32 API, он будет выглядеть немного иначе, но принцип тот же.

Проверьте выбрать (2). Я не совсем уверен, как работает libpurple, но если он разрешает уведомление через дескриптор файла (например, файл или сокет), тогда select - это ваше решение.

Вы также можете попробовать создать отдельный поток с помощью pthread_create(3). Таким образом, он может блокировать get (или что-то еще), в то время как остальная часть вашей программы делает это.

Другие вопросы по тегам