I'm working on writing a socket server to handle multiple connections. I've tried setting up a non-blocking socket so socket_accept will return false and won't halt the script after all incoming connections are handled. Here's my code so far:
<?php
include("config.php");
error_reporting(E_ALL);
set_time_limit(0);
if (($mainSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false)
die("Error:\tCould not create main socket.\n");
if (!socket_bind($mainSocket, $config["bind_address"], $config["bind_port"]))
die("Error:\tCould not bind socket to address and port.\n");
if (!socket_listen($mainSocket))
die("Error:\tCould not begin listening for incoming connections.\n");
if (!socket_set_nonblock($mainSocket))
die("Error:\tCould not set nonblocking mode for main socket.\n");
socket_set_option($mainSocket, SOL_SOCKET, SO_REUSEADDR, 1);
include("includes/client.php");
$null = null;
$clients = array();
$newSocket = false;
$newClient = null;
while (true) {
// check for sockets being written to
$readSockets = array($mainSocket);
foreach ($clients as $client)
$readSockets[] = $client->socket;
socket_select($readSockets, $null, $null, null);
if (in_array($mainSocket, $readSockets)) /* one or more clients hitting the main socket for a connection */ {
// get each new connection and set up a client object
while (($newSocket = socket_accept($mainSocket)) !== false) {
$clients[] = $newClient = new Client();
$newClient->socket = $newSocket;
}
}
// loop through connected clients looking for incoming data
foreach ($clients as $clientID => $client) {
if (in_array($client->socket, $readSockets)) /* current client is writing a letter to us :3 */ {
$totalData = $data = "";
do {
$totalData .= $data = socket_read($client->socket, 1024, PHP_BINARY_READ);
}
while ($data != "");
if ($totalData == "")
unset($clients[$clientID]);
else var_dump($totalData);
}
}
}
?>
config.php sets the $config array and includes/client.php contains the Client class, which has a public variable $socket. I'm getting the error:
Warning: socket_accept(): unable to accept incoming connection [ 0 ]: A non-blocking socket operation could not be completed immediately.
in server.php on line 39
I'm trying this on Windows with PHP 5.2.6. Could this be one of the bugs in the PHP sockets library, or is there an error in my code that I'm not seeing? Is there any way around this while maintaining non-blocking behavior?