Использование php в качестве клиента сокета для сервера C ++ - PullRequest
0 голосов
/ 25 ноября 2011

У меня странная проблема.

Я написал небольшой сервер на C ++, который хранит объект в двоичном формате в файле.

Я успешно протестировал его с помощью telnet.

telnet 127.0.0.1 1234
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
store 1 1 5 1
store 1 1 5 2

Вывод на сервер теперь

Command : store 1 1 5 1
Command : store 1 1 5 2

Поскольку мы собираемся использовать php для хранения этой информации, я написал небольшой скрипт php, который будет отправлять 10 команд на наш сервер.

<?php

    $socket = socket_create(AF_INET,SOCK_STREAM,0);
    socket_connect($socket,"127.0.0.1",1234);

    for($i = 0;$i < 10;$i++){

        $command = "store 1 $i 5 1\r\n";

        echo $command;

        socket_write($socket,$command,strlen($command));

    }

    socket_close($socket);

?>

Проблема в том, что теперь вывод с сервера:

Command : store 1 0 5 1store 1 1 5 1store 1 2 5 1store 1 3 5 1store 1 4 5 1store 1 5 5 1store 1 6 5 1store 1 7 5 1store 1 8 5 1store 1 9 5 1

\ r \ n не распознан.После поиска я обнаружил, что, добавив usleep (10000) после функции socket_write, он на самом деле будет работать.

Я пытаюсь избежать использования этого обходного пути, поэтому у меня возникают вопросы:

Почему usleep это исправляет?Как я могу сделать это без usleep?

Спасибо за чтение!

1 Ответ

0 голосов
/ 25 ноября 2011

Нам бы наверняка пришлось видеть ваш сервер C ++, но я подозреваю, что вы неправильно анализируете там данные.

TCP является потоковым протоколом, и в протоколе нет границ для данных в пакетах. Поэтому, когда вы отправляете несколько команд «store», все они могут появляться в одном и том же TCP-пакете. Затем, когда вы звоните recv(), вы можете получить несколько «магазинов». Однако из-за времени и того факта, что telnet может отправлять каждую строку в своем собственном пакете, каждый вызов recv() может получить одну команду "store".

Когда вы включаете usleep, вы фактически задерживаете очередь очередных данных, и TCP прекращает ожидание и отправляет «store» в пакете самостоятельно.

На вашем сервере вы должны

  1. Ожидайте, что несколько "хранилищ" будут извлечены из recv(),
  2. Ожидается, что один «магазин» будет разделен на несколько recv() вызовов.

usleep - это хак, который может не всегда работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...