Цикл хоче вісім байтів відповіді SOCKS. Він отримав три. Наступне читання повертає b'', цикл додає його, перевіряє довжину і знову намагається нескінченно.

Це помилка обробки EOF, а не повільний проксі, якому потрібен довший тайм-аут. Під час звичайного приймання через потоковий сокет порожній рядок байтів означає, що партнер від'єднався. Решта п'ять байтів не прийдуть цим з'єднанням.

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

Встановіть передбачуваний тайм-аут сокета перед операцією та читайте довжини полів, які визначає протокол проксі. Один прийом може повернути лише частину відповіді. І навпаки, запит великого фіксованого буфера не робить кожну адресу SOCKS такої довжини.

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

Зберігайте, скільки байтів очікувалося та було отримано, не записуючи корисні навантаження облікових даних. «EOF після трьох із восьми байтів відповіді» пояснює зламаний обмін значно краще, ніж «проксі знову завис».

Схожі статті