Правильное использование socket_select()

Как правильно использовать socket_select в PHP для отправки и получения данных?

У меня есть подключение к серверу, которое позволяет использовать пакеты пакетов TCP и UDP, я использую оба. В этих соединениях я отправляю и получаю пакеты на один и тот же порт, но TCP-пакет будет отправлен на один порт (29999), а UDP будет отправлен на другой порт (30000). Тип передачи будет AF_INET. IP-адрес будет кольцевым 127.0.0.1.

У меня много вопросов о том, как создать сокетное соединение в этом сценарии. Например, лучше ли использовать socket_create_pair для установления соединения, или используйте просто socket_create, а затем socket_connect, а затем реализовать socket_select?

Существует вероятность того, что никакие данные не будут отправлены с сервера на клиент, и клиент должен поддерживать соединение. Это будет сделано с помощью функции тайм-аута в вызове socket_select. Если в течение установленного времени данные не будут отправлены, функция socket_select прервется, и тогда можно будет отправить пакет проверки активности. Следующий сценарий относится к клиенту.

// Create
$TCP = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$UDP = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

// Misc
$isAlive = TRUE;
$UDPPort = 30000;
define('ISP_ISI', 1);

// Connect
socket_connect($TCP, '127.0.0.1', 29999);
socket_connect($UDP, '127.0.0.1', $UDPPort);

// Construct Parameters
$recv = array($TCP, $UDP);
$null = NULL;

// Make The Packet to Send.
$packet = pack('CCCxSSxCSa16a16', 44, ISP_ISI, 1, $UDPPort, 0, '!', 0, 'AdminPass', 'SocketSelect');

// Send ISI (InSim Init) Packet
socket_write($TCP, $packet);

/* Main Program Loop */
while ($isAlive == TRUE)
{
    // Socket Select
    $sock = socket_select($recv, $null, $null, 5);

    // Check Status
    if ($sock === FALSE)
        $isAlive = FALSE; # Error
    else if ($sock > 0)
        # How does one check to find what socket changed?
    else
        # Something else happed, don't know what as it's not in the documentation, Could this be our timeout getting tripped?
}

person Mark Tomlin    schedule 07.04.2010    source источник


Ответы (1)


Я немного запутался - кажется, вы пытаетесь справиться с асинхронными запросами, поступающими через 2 сокета, но оба действуют как клиенты? Это очень необычный сценарий. Пытаться реализовать их с использованием разных протоколов (tcp и udp) еще более странно (H323 VOIP — единственное известное мне приложение, которое делает это). Беглый гугл подсказывает, что вы пытаетесь написать клиент для LFS — но зачем вам одновременно работающий клиент TCP и UDP? (Кстати, они публикуют подходящий клиентский код PHP в своей Wiki по адресу http://en.lfsmanual.net)

Сокет, в котором есть данные, ожидающие чтения, будет находиться в массиве $recv после вызова socket_select() (т. е. массив обрезается и должен быть повторно заполнен перед следующей итерацией socket_select()).

Если socket_select возвращает 0, это просто означает, что сокеты не блокируются и ни один из них не имеет доступных данных.

ХТН

C.

person symcbean    schedule 07.04.2010
comment
Да, это действительно для LFS, и если вы копнете немного глубже, вы обнаружите, что я был автором клиентского кода LFS InSim, который можно найти на странице руководства LFS. Я ищу лучший способ обработки пакетов менее ресурсоемким способом. Я слышал, что лучший способ сделать это — через socket_select, и мне было интересно, как правильно это реализовать. - person Mark Tomlin; 07.04.2010
comment
Поэтому я должен затем переместить $recv = array($TCP, $UDP); в цикл while. - person Mark Tomlin; 07.04.2010