Клиенты вообще знают о существовании друг друга? Не видно никакого механизма именования клиентов и передачи этих имен. То есть, каждый клиент в данном коде будет просто рассылать сообщения во все сокеты, даже в свой.
В качестве имени можно рассылать индекс в массиве, присвоенный при подключении. Но на клиенте должна быть обработка этих индексов.
По идее, должно получиться так, что каждый клиент будет знать о всех или о группе сокетов, с которыми будет общаться: о добавлении новых, об удалении закрытых. И здесь же появится возможность отправлять на один определенный сокет по его имени какое-либо обращение. Естественно, сервер должен по указанным в сообщениях именам выбирать сокеты и писать только в них.
Тут напрашивается какой-нибудь "протокол" поверх сокетов, чтобы различать личные и общие сообщения, хотя хватит какого-нибудь строкового условия — тут по вкусу.
Ну а что я вижу в коде:
if( 'nw' == $received_text[1] )
здесь, видимо, должны разделяться личные и общие сообщения. Тогда следующей строкой можно
if( $received_text[2] > -1 )
Потом этот элемент взять за тот самый индекс и делать
@socket_write( $clients[ $received_text[2] ], $msg, strlen($msg) );
Но тут вдруг в массиве "клиенты" по индексу не окажется сокета?