views:

209

answers:

1

What is the correct way to use socket_select within PHP to send and receive data?

I have a connection to the server that allows for both TCP & UDP packet connections, I am utilizing both. Within these connections I'm both sending and receiving packets on the same port, but the TCP packet will be sent on one port (29999) and UDP will be sent on another port (30000). The transmission type will be that of AF_INET. The IP address will be loopback 127.0.0.1.

I have many questions on how to create a socket connection within this scenario. For example, is it better to use socket_create_pair to make the connection, or use just socket_create followed by socket_connect, and then implement socket_select?

There is a chance that no data will be sent from the server to the client, and it is up to the client to maintain the connection. This will be done by utilizing the time out function within the socket_select call. Should no data be sent within the time limit, the socket_select function will break and a keep alive packet can then be sent. The following script is of the client.

// 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?
}
A: 

I'm a bit confused - you seem to be trying to deal with asynchronous requests coming in via 2 sockets but both are acting as clients? This is a very unusual scenario. To be trying to implement them using different protocols (tcp and udp) is even odder (H323 VOIP is the only applciation I know of which does this). A quick google suggests you are trying to write a client for LFS - but why do you need a TCP and UDP client running at the same time? (BTW they publish suitable PHP client code on their Wiki at http://en.lfsmanual.net )

The socket which has data waiting to be read will be in the $recv array after the call to socket_select() (i.e. the array is trimmed down and needs to be repopulated before the next iteration of socket_select()).

If socket_select returns 0 it just means that the sockets are non-blocking and none of them have any data available.

HTH

C.

symcbean
Yes this is indeed for LFS, and if you digg alittle deeper you will find that I was the author of the LFS InSim client code found on the LFS Manual page. What I'm looking for is a better way to handle the packets in a less resource intensive way. I hear the best way to do that is via socket_select and I was wondering what the correct way to implement this was.
Mark Tomlin
So I should then move `$recv = array($TCP, $UDP);` into the while loop.
Mark Tomlin
Yes that would be a good idea.
symcbean