C fwrite () застрял процессор на 100% - PullRequest
0 голосов
/ 05 июля 2019

У меня есть главный ПК и несколько ведомых сетевых устройств.Мастер создает процесс для каждого раба с вилкой.Каждый процесс пытается подключиться к соответствующему устройству и захватить данные через TCP.Все работало нормально, но у меня была переустановка на master ubuntu-> kali (4.19.0-kali1-amd64) и сбор данных остановлен. Входные данные должны быть между 10-40Mb / s

Разветвление, ведомые,и сбор данных, кажется, хорошо.Как я видел, проблема заключается в fwrite.Если я изменю fwrite на printf и перенаправлю данные в файл, я получу захваченные данные.

Интересные примечания после отладки:

- Один поток ЦП всегда был 100%

-Всегда записал данные 16K

С использованием printf вместо fwrite все было хорошо.

И еще одно интересное замечание: я думаю, что это другая проблема, но мой сетевой интерфейс не видитвходящие пакеты.Он захвачен, но не может использоваться для статистики, как netstat.

while(1)
      {
        valread = read( sock , buffer, 1024); //blocking
        //printf("%s",buffer); //try with printf
        if (valread > 0)
        fwrite(buffer,1,valread,fp); //stucked?
      }

1 Ответ

5 голосов
/ 05 июля 2019

Ваш цикл не останавливается, когда вы получаете EOF или ошибку, он просто продолжает пытаться прочитать из сокета.

while(1)
{
    valread = read( sock , buffer, 1024);
    if (valread > 0) {
        fwrite(buffer,1,valread,fp);
    } else if (valread < 0) {
        perror("read from sock");
        break;
    } else {
        break;
    }
}

EOF произойдет, когда устройство закроет сетевое соединение.

Если сокет неблокирующий, read() может вернуть -1 с ERRNO == EWOULDBLOCK, когда ничего не готово для чтения.Вы должны проверить это и выйти из цикла (используйте select() или epoll(), чтобы дождаться готовности сокета, прежде чем пытаться читать из него).

Кстати, вы не должны использоватьprintf(), поскольку read() не добавляет нулевой терминатор в буфер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...