двунаправленная розетка (неблокирующая) с - PullRequest
1 голос
/ 29 ноября 2011

Я пытаюсь сделать что-то вроде чата через TCP-сокеты.Серверная часть реализована в php и (должна) нормально работать.

Нет, я столкнулся с проблемой на стороне клиента (реализовано в c [c99]):

Мне бы хотелосьпрослушивать (читать) «новые байты» с сервера, и я также хотел бы отправлять (записывать) «несколько байтов» на сервер всякий раз, когда пользователь вводил новые данные.

Теперь вопрос: ->Как я могу прослушивать входящий трафик (читать) и по-прежнему иметь возможность каждые 1 секунду вызывать функцию обратного вызова, где я могу проверять наличие новых байтов для отправки на сервер?Я знаю, что должен использовать select (системный вызов), но у меня нет идеи, как обрабатывать тайм-аут и т. Д. Select также блокируется на определенное время.

Спасибо за любой пример.

Ответы [ 3 ]

1 голос
/ 29 ноября 2011

Для этого можно использовать функцию select. Он может проверить, есть ли новый вход в сокете для чтения, и у него есть тайм-аут, поэтому его можно использовать и для вашего таймера.

Он существует в той или иной форме во всех основных операционных системах. Просто выполните поиск Google для socket select <your operating system> example, и вы получите множество результатов.


Последний аргумент select используется для тайм-аута. Это указатель на struct timeval, структуру, которая содержит поля для установки времени ожидания.

Если этот указатель передается как NULL, то тайм-аут не существует, и select может блокироваться бесконечно.

Чтобы установить тайм-аут, вам необходимо установить в поле tv_sec структуры timeval количество секунд, а в поле tv_usec - количество микросекунд (должно быть меньше миллиона). Вы можете установить тайм-аут на ноль, т. Е. Просто быстрый опрос, установив эти поля на ноль.

Если select возвращает ноль, значит, был тайм-аут.

Пример с тайм-аутом 1,5 секунды:

for (;;)
{
    fd_set readset;
    int maxfd;

    /* Initialize and set `readset` and `maxfd` */

    struct timeval tv;
    tv.tv_sec  = 1;
    tv.tv_usec = 500000;

    int res = select(maxfd + 1, &readset, NULL, NULL, &tv);

    if (res == -1)
        perror("select");  /* Error */
    else if (res == 0)
    {
        /* Timeout, do something */
    }
    else
    {
        /* A socket in `readset` is readable */
    }
}

Если select возвращает до тайм-аута, структура timeval изменяется так, чтобы содержать оставшееся время тайм-аута.

0 голосов
/ 29 ноября 2011

Используйте вызов system .Вы также можете найти это полезным.

0 голосов
/ 29 ноября 2011

Используйте системный вызов select , с параметром timeout, установленным по необходимости. Руководство Биджа все еще является хорошим источником с большим количеством примеров кода.

...