PehJota Posted January 17, 2009 Share Posted January 17, 2009 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? Quote Link to comment Share on other sites More sharing options...
RussellReal Posted January 17, 2009 Share Posted January 17, 2009 I am not seeing what you need this for: 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; } } the if while (($newSocket = socket_accept($mainSocket)) !== false) { $clients[] = ($newClient = new Client()); $newClient->socket = $newSocket; } Quote Link to comment Share on other sites More sharing options...
PehJota Posted January 17, 2009 Author Share Posted January 17, 2009 True, I suppose I don't need that if I'm using non-blocking behavior. I just saw it done on a tutorial with blocking behavior and didn't think to remove it. I've decided to try using default blocking behavior since I couldn't get non-blocking to work. I tried splitting the socket_select call into two calls, one for the master socket and one for the clients. Then I noticed and remembered that socket_select blocks, so no incoming data is read until another connection is made. I then found the same problem in my read loop -- socket_read blocked execution until more data was written, so I'll have to modify it to check the last character for chr(0) or something. But I got it to work now, with blocking behavior. Not as easy to accept all connections in one iteration and read all data from the socket in one shot, but I'll work around it Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.