выберите () висит бесконечно - PullRequest
4 голосов
/ 05 июня 2010

У меня есть приложение, которое работает на встроенном Linux (старое ядро, 2.6.18). Я использую Live555. Иногда, когда камера сильно загружена, мой RTSP-сервер (созданный с использованием Live555) зависает на неопределенное время - кажется, никакие соединения или уговоры не могут заставить его выйти из строя, если не считать сброса приложения.

Я сузил область видимости до этого кода:

static int blockUntilReadable(UsageEnvironment& env,
                  int socket, struct timeval* timeout) {
  int result = -1;
  do {
    fd_set rd_set;
    FD_ZERO(&rd_set);
    if (socket < 0) break;
    FD_SET((unsigned) socket, &rd_set);
    const unsigned numFds = socket+1;

    result = select(numFds, &rd_set, NULL, NULL, timeout);  <--HANG

Тайм-аут - это, конечно, указатель NULL, который указывает, что он должен блокироваться до тех пор, пока один из сокетов не станет читаемым. Проблема в том, что не имеет значения, подключаюсь ли я к серверу RTSP, он просто блокируется на неопределенный срок.

Я сделал netstat -an, и он всегда выдает что-то вроде:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:5222            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5800            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5802            0.0.0.0:*               LISTEN
tcp       21      0 0.0.0.0:554             0.0.0.0:*               LISTEN

Когда он находится в состоянии сбоя, я всегда вижу 21 на Recv-Q, который равен «Количество байтов, не скопированных пользовательской программой, подключенной к этому сокету».

Кто-нибудь имеет представление о том, что может идти на юг или как я могу устранить эту проблему?

1 Ответ

2 голосов
/ 05 июня 2010

Этот код выглядит довольно солидно. Мне немного любопытно, почему вы кастуете на unsigned int, но это ничего не должно повредить.

Некоторые мысли:

Это не висит там, где ты думаешь. Надеюсь, вы проверили это дважды. (Проверить еще раз?)

Ваша интерпретация netstat неверна. Эта часть, как отмечается на странице руководства, предназначена для сокетов «Установлено» - ваш - слушатель, который является следующим предложением: «Прослушивание: начиная с ядра 2.6.18 этот столбец содержит текущее отставание синхронизации».

Это похоже на огромное отставание ... Что заставляет меня думать, что вы не принимаете () - возможно, потому что вы застряли в select (). Что это выбор () на вашем сокете прослушивания, верно?

Наконец, дважды проверьте, что вы вызываете select () в правом сокете . то есть распечатайте этот аргумент сокета и посмотрите, должен ли он быть таким.

По сути, проверьте: 1) он зависает в select () и 2) аргументы для выбора верны. Я подозреваю, что один из этих двух не соответствует действительности.

...