При повторной итерации read, по идее, должен вернуть 0, так как все прочитано
Неа, не так это работает. 0 из read возвращается в одном единственном случае: если та сторона закрыла сокет на передачу и все посланные ею данные получены. В противном случае (сокет не закрыт) поведение зависит от настроек сокета: синхронный сокет при попытке чтения может заблокироваться в функции
read
или вернуть из неё -1 (и установить
errno
, например, в
EINTR
). Асинхронный сокет вернёт из
read
-1 и установит
errno
в
EAGAIN
или
EWOULDBLOCK
.
Ваш HTTP-сервер наверняка оставляет соединение открытым после того как прислал ответ на первый запрос, это можно понять по наличию заголовка
Connection: Keep-Alive
или отсутствию заголовка
Connection: close
в его ответе если это
HTTP/1.1
. Его можно попросить закрыть соединение после ответа, послав запрос с заголовком
Connection: close
или можно избежать блокировки в
read
прочитав только данные ответа размер которых прислан в заголовке ответа
Content-Length
.