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>');

?>

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.