PHP Sockets - это полуработающий - PullRequest
7 голосов
/ 04 февраля 2011

Итак, у меня есть mIRC, который прослушивает (имейте это в виду) порт 1235, и я попытался создать скрипт php для подключения к такому порту на моем локальном сервере.

Мой localhost - это чистый Apache + PHP с mIRC, запущенным на другом компьютере (внутри локальной сети).

Скрипт работает наполовину как: 1) подключается к порту 1235 2) отправляет $ i 2.1) но с другой стороны сообщение не принимается (иначе я получаю событие чтения носка, но текст не появляется) 3) читает все входящие сообщения корректно 4) он закрывается, когда 'end' является сообщением барабанная дробь 5) это работает только если функция while отсутствует. 5.1) ака Inifi-загрузка. он показывает только эхо, когда сокет закрыт через 'end'

вот код, который является простым примером, который я нашел на php.net, заранее спасибо:)

    <?php
//The Client
error_reporting(E_ALL);

$address = "192.168.1.101";
$port = 1235;

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
    echo "socket successfully created.\n";
}

echo "Attempting to connect to '$address' on port '$port'...";
$result = socket_connect($socket, $address, $port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
    echo "successfully connected to $address.\n<br>";
}
$allow = true;
$i = 0;
while ($allow == true)
{
    $i++;
    echo "Sending $i to server.\n<br>";
    socket_write($socket, $i, strlen($i));

    $input = socket_read($socket, 2048);
    if ($input == 'end') {
        $allow = false; 
    }
    echo "Response from server is: $input\n";
    sleep(5);
}

echo "Closing socket...";
socket_close($socket);
?>

это то, что я получаю в браузере, после произнесения 'end'

сокет успешно создан. Попытка подключиться к «192.168.1.101» в порту '1235' ... успешно подключен к 192.168.1.101. Отправка 1 на сервер. Ответ от сервера: хорошо Ответ от сервера: end

это в mIRC:

тест: 89.152.172.21 в! читать близко Blockquote

если я оставил его работать в течение часа, умножьте «чтение» на 60 и «отправка N + 1 на сервер» но это только показывает ПОСЛЕ закрытия носка (или остановив какое-то время)

Ответы [ 3 ]

2 голосов
/ 27 марта 2011

У вас "простые" звонки socket_write() и socket_read(). К сожалению, функции сокетов ненадежны по конструкции (это поведение унаследовано от сокетов BSD). Вы не можете просто позвонить socket_write() и ожидать, что он на самом деле будет записывать байты (как бы странно это ни звучало ...)

PHP руководство цитата:

socket_write () не обязательно записывает все байты из данного буфера. Действительно, в зависимости от сетевых буферов и т. Д. Записывается только определенный объем данных, даже один байт, хотя ваш буфер больше. Вы должны остерегаться, чтобы не забыть непреднамеренно передать остальные данные.

Вы должны проверить, сколько байтов было записано, и повторять попытки до тех пор, пока не будет отправлено все, что вы хотели.

То же самое относится и к чтению. Чтение вызова может считывать столько, сколько вы запросили или меньше , и ожидается, что вы повторите попытку.

Убедитесь, что сокеты заблокированы, а затем вызовите чтение / запись в цикле, или используйте (одинаково ужасно) select() вызов, чтобы узнать, какие сокеты могут содержать некоторые данные или могут закончили отправку.


Если вы хотите, чтобы API не был таким PITA, вместо этого используйте streams , которые имеют надежные операции чтения / записи.

Если вам необязательно нужен PHP, взгляните на Node JS , который является специально разработанным сервером / средой для программ с долгоживущими сетевыми подключениями.

0 голосов
/ 26 марта 2011

Из одного из примечаний в документации: http://php.net/manual/en/function.socket-write.php

Некоторые клиенты (например, XMLSocket Flash) не запускают событие чтения, пока не будет получена новая строка.

Попробуйте изменить код:

socket_write($socket, $i, strlen($i)); на: socket_write($socket, $i.'\n', strlen($i)+1);

0 голосов
/ 04 февраля 2011

Изменение

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

Кому:

socket_write($socket, strval($i), strlen(strval($i)));

Вы предоставляете целое число, в котором PHP ожидает строку.

...