То есть. Server: Код (Text): ... while(1) { ... send(sock, buffer, 1, 0); Sleep(10000); ... } ... Client: Код (Text): ... while(recv(sock, buffer, 1, 0)) { ... std::cout << '.'; ... } std::cout << "ok!"; ... ok никогда не выведится. А вот точки будут до бесконечности.
bug1z Ну это очень весело. Не удивительно, что выхода из цикла не происходит до graceful shutdown. И что по Вашему мнению возвращает функция recv?
1. количество принятых байтов 2. 0 если соединение разорвано 3. SOCKET_ERROR во всех остальных случаях. но самое веселое, что после такой записи: ... int result; while((result = recv(sock, buffer, 1, 0)) && result != SOCKET_ERROR) { ... std::cout << '.'; ... } std::cout << "ok!"; ... картина не меняется, хотя по логике теперь все верно.
bug1z По логике практически ничего не поменялось. Только добавилось ещё одно незначительное условие выхода из цикла. Ну так а чего Вы тогда ожидаете от этого цикла? recv нормально возвращает управление при каждом получении очередной пачки данных. Как только данные пришли, на консоль выводится точка, и цикл повторяется заново очередным вызовом recv с ожиданием следующей порции. Выход из цикла, естесственно, возможен только тогда, когда возвращается нуль (или SOCKET_ERROR в последнем варианте), что как раз и происходит при разрыве соединения.
А если сервер шлет разные данные с неким интервалом, а я в цикле вызываю рекв - как мне разделить эти данные? То есть распихать данные по файлам. Как это реализовывается? Если с реконнектом ясно - связь разорвалась - значит этот файл принят полностью. А как быть с постоянным соединением? Размер файла то не известен. На сколько правильно решение передавать первыми N байтами файла его размер?
А как можно объяснить такую ситуацию, что без слипа данные приходят с куском нулей посередине, а со Sleep(10) все хорошо?
bug1z Видимо, читаете данные неправильно. Мой хрустальный шар показывает, что возвращаемое recv значение не проверяется (или проверяется недостаточно), а вместо него для вывода используется константный размер.