Вы писали, что проблема у вас именно, когда строки с socket_close нет, из чего я и исходил. Закрыть он, конечно, может не успеть, особенно, если клиент не ожидает этого и со своей стороны закрывать ничего не собирается.
TIME_WAIT — это нормально, никуда не деться от них. Не забывайте про SO_REUSEADDR и проблем быть не должно.
Вот например, что наковырялось. Не то чтобы я с этим очень хорошо знаком, но встречался и пришлось почитать маны, чтобы не делать глупых ошибок.
Да, про socket_read(), конечно так. Reset не нужен, foreach его все равно сделает.
И да, я свои примеры, естественно, не тестировал :)
Вообще, написание сетевых серверных приложений, особенно работающих с длинными соединениями и многими клиентами, требует большой аккуратности. Т.е. программа-пример из любого howto по сокетам будет работать как надо, но только до тех пор, пока не заглючит сеть, клиенты не начнут неожиданно рвать соединения и прочая, и прочая.
Так, в примере с селектом я делаю socket_read($fd, 4096) и перехожу к обработке данных. По идее никто не гарантирует, что я так вычитаю сообщение целиком (на это можно только надеяться, если сообщение достаточно короткие). По-хорошему, надо как-то договариваться о длине сообщения и читать из сокета (через select) пока не наберется эта длина. Для сообщений переменной длины можно ее передавать перед самим сообщением (как первые 4 байта пакета, например).