KIVagant
Junior Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору Добрый день всем. Надеюсь, мой сегодняшний пост поможет кому-то не терять лишнего времени. Как я уже давно писал выше, у меня возникала проблема, в результате которой я не мог отправить в сокете с помощью socket_write сообщение клиенту, пока не "проталкивал" его предварительно ответом от самого клиента. То есть, когда я делал так: Код: // $buffer - это пришло от клиента // $result - это сформированный ответ клиенту $len=strlen($buffer); $result = socket_write ( $client, $buffer, $len ); $len=strlen($result); $result = socket_write ( $client, $result, $len ); | ... то это работало и клиент получал на вывод $result. Но при этом иногда алгоритм сбоил, пакеты путались и я не мог никак понять причины. После длительных изысканий я сделал следующее - Код: $result = socket_write ( $client, $buffer.$result, $len ); | Таким образом я пытался проверить свою мысль, что отправка эхо-ответа действительно напрямую влияет на получение клиентом данных. И, что удивительно - так и получилось. Но с одним нюансом - в клиенте отображалось наборот - сначала ответ сервера (одинаковый текст), а затем то, что клиент серверу отправлял (буффер). Код: 1. Клиент - шлем "test". 2. Сервер - шлем в ответ "{ошибка}"."test". 3. Клиент - получаем и выводим в строку: "test"."{ошибка}". | И вот это зеркальное отражение и натолкнуло на мысль, что текст "{ошибка}" все-таки берется не из текущего ответа сервера, а из предыдущего! Для проверки я стал нумеровать ответы сервера и догадка подтвердилась. Дальше все просто - я догадался, что в данных клиента (буффере) содержится спец-символ, по которому определяется окончание пакета. Я думал, что за это отвечает socket_write, но оказывается все не так. Проанализировав данные от клиента, я увидел в окончании "\u0000" - то есть "NUL". Языком PHP этот символ можно вывести с помощью "\0". Я стал добавлять этот символ ко всем отсылаемым ответам - и все заработало. Код: $result.="\0"; $len=strlen($result); $result = socket_write ( $client, $buffer.$result, $len ); | Может для кого-то это есть само собой разумеющееся, но у меня на осознание простой истины ушло очень много бессмысленно потерянного времени. Добавлено: Кстати, кто может объяснить по-русски разницу между socket_recv() и socket_read(). Какую из них лучше использовать? И для чего используют разные константы, например MSG_WAITALL в socket_recv() или, к примеру PHP_BINARY_READ в socket_read()? Я нашел в комментариях на php.net интересную функцию, заменяющую стандартный socket_read(,,PHP_NORMAL_READ), но не очень понял - для чего? Может кто по-лучше на буржуйском шпрехает и будет не ленив пояснить? Заранее спасибо. |