Цикл хочет получить восемь байт ответа SOCKS. Он получил три. Следующее чтение возвращает b'', цикл добавляет его, проверяет длину и снова пытается до бесконечности.

Это ошибка обработки EOF, а не медленный прокси, которому нужен более длительный тайм-аут. При обычном приёме через потоковый сокет пустая строка байтов означает, что партнёр отключился. Оставшиеся пять байт не придут по этому соединению.

Помощнику точного чтения нужны три разных исхода: накапливать непустые фрагменты, завершаться ошибкой при EOF до нужной длины и передавать тайм-аут или другую ошибку сокета. Эти случаи не должны сливаться в один общий цикл повторных попыток.

Задайте предполагаемый тайм-аут сокета перед операцией и читайте длины полей, указанные протоколом прокси. Один приём может вернуть только часть ответа. И наоборот, запрос большого фиксированного буфера не делает каждый адрес SOCKS такой длины.

Не исправляйте зависимость, вставляя старый фрагмент MSG_WAITALL в её исходный код и предполагая, что он покрывает EOF, сигналы и поведение платформы. Предпочитайте поддерживаемое исправление в сопровождаемой реализации или сознательно реализуйте контракт помощника, когда парсер — ваш код.

Сохраняйте, сколько байт ожидалось и было получено, не записывая полезные нагрузки учётных данных. «EOF после трёх из восьми байт ответа» объясняет сломанный обмен гораздо лучше, чем «прокси снова завис».

Похожие статьи