Jump to content

[SOLVED] Non-blocking Socket Can't Accept Connection


PehJota

Recommended Posts

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?

Link to comment
Share on other sites

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;
	}

Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.