hirthwork

Каждый раз когда вы собираетесь использовать chunked transfer encoding,
выставляйте tcp_nodelay = true.
Почему? А представьте, что стреляете вы, скажем, json'ом. И вот уходит у вас
такой небольшой чанк (после которого вы делаете flush):

14
{"hello":"world"}

Принимающая сторона этого ответа ждала, вожделела и висела в read(). Как только
ваши данные прилетят на другой конец, приложение прочитает чанк из сокет-буфера

А теперь представьте, что у принимающей стороны включён delayed-ack.
Например, у меня он включён, как оказалось.

Все данные вы отослали и теперь нужно бы послать нулевой чанк, чтобы сказать
что у вас данные закончились. Вот только ack на прошлый пакет ещё не пришёл, и
нулевой чанк, запихнутый в сокет-буфер вами, никуда не отсылается, ибо ack'а
ждёт. А принимающая сторона, в свою очередь, ждёт от вас этого нулевого чанка.
Вот и сидят две программы по разные стороны сокета и ждут неизвестно чего, пока
принимающая сторона таки не соблаговолит отложенный ack послать.