Jump to content

Help with sockets - socket_accept killing script?


kristopherWindsor

Recommended Posts

My script seems to work, if someone connects to the script a few seconds after I call socket_accept. But if I wait 20 seconds or so before launching the client, then the client doesn't connect properly, and the script ends about 5 seconds later.

That is, whether the client connects 20 seconds after the script calls socket_accept, or 2 minutes after, the script doesn't terminate until shortly after the client tries to connect. And the script isn't supposed to be terminating. I have turned all the error reporting on, but I get no error when it terminates, and I know my script isn't ending properly.

If I connect quickly, the script runs and terminates properly. Any ideas why the client needs to connect quickly for this to work, or how it can be fixed? :)

 

Here's my script FWIW:

<?php

// (C) 2009 Kristopher Windsor

error_reporting(E_ALL);

$MAX_CLIENTS = 8;
$clients = array(null, null, null, null, null, null, null); // sockets; null -> not open; client set to null if error
$connection = array();

function start ()
{
set_time_limit(60 * 10);
echo '<html><body>';
echo 'Kristopher Windsor\'s game server v1.0<br><br>';
}

function finish ($m)
{
die("$m<br>The server has finished. If it completed successfully, it will restart automatically.</body></html>");
}

function open ()
{
global $clients, $connection;

echo 'Opening port ' . $connection['port'] . ' on ' . $connection['ip'] . ' (timestamp ' . time() . ')<br>';

$connection['socket'] = socket_create(AF_INET, SOCK_STREAM, 0);
if ($connection['socket'] === false ||
	!socket_bind($connection['socket'], $connection['ip'], $connection['port']) ||
	!socket_listen($connection['socket'], 3))

	finish('Error: the port is in use (the server is probably already running)');

echo 'Waiting for clients<br>';

for ($i = 0; $i < $connection['clients']; $i ++)
	{
	$clients[$i] = socket_accept($connection['socket']);
	dispatch('Player ' . ($i + 1) . ' of ' . $connection['clients'] . ' connected');
	}

echo 'Clients connected<br>';
}

function close ()
{
global $clients, $connection;

socket_shutdown($connection['socket'], 2);
socket_close($connection['socket']);
}

function relay ()
{
global $clients, $connection;

foreach ($clients as $c => $oneclient)
	{
	if ($oneclient == null)
		continue;

	socket_clear_error();
	$chunk = socket_read($oneclient, 1024);
	checkconnection($c);

	if (trim($chunk) == '')
		continue;

	$chunk = str_replace("\n", ' ', $chunk);
	$chunk = str_replace("\r", ' ', $chunk);
	$message = explode(' ', $chunk);

	foreach ($message as $i => $m)
		if (trim($m) != '')
			dispatch(($c + 1) . trim($m));
	}
}

function dispatch ($m)
{
global $clients, $connection;

echo "Sending message: $m<br>";

foreach ($clients as $c => $oneclient)
	{
	if ($oneclient == null)
		continue;

	socket_clear_error();
	socket_write($oneclient, $m . "\n", strlen($m) + 1);
	checkconnection($c);
	}
}

function checkconnection ($c)
{
global $clients, $connection;

if ($clients[$c] == null || socket_last_error() != 104)
	return;

socket_close($clients[$c]);
$clients[$c] = null;
dispatch('Player ' . ($c + 1) . ' closed the connection');
dispatch('END');
}

function connectedclients ()
{
global $clients, $connection;

$r = 0;
foreach ($clients as $c => $oneclient)
	if ($oneclient != null)
		$r ++;

return $r;
}

start();
if (!isset($_GET['port']) || !isset($_GET['clients']))
finish('Please specify the port and clients.');

$connection['ip'] = "...[removed]...";

$connection['port'] = $_GET['port'];
if ($connection['port'] < 1000 || $connection['port'] > 50000)
finish('Please select a better port number');

$connection['clients'] = $_GET['clients'];
if ($connection['clients'] < 1 || $connection['clients'] > $MAX_CLIENTS)
finish('Please select a better number of clients');

open();
do
{
relay();
usleep(1000 * 1000 / 50); // 50th of second
} while (connectedclients() > 0);
close();

finish('<script>setTimeout(\'location.href = "server.php?port=' . $connection['port'] .
'&clients=' . $connection['clients'] . '"\', 5000)</script>');

?>

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.