php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42423 client disconnect not detected by socket_select()
Submitted: 2007-08-25 13:13 UTC Modified: 2007-08-25 20:17 UTC
Votes:2
Avg. Score:1.0 ± 0.0
Reproduced:0 of 2 (0.0%)
From: tinyunderscoregrasshopper at hotmail dot com Assigned:
Status: Not a bug Package: Sockets related
PHP Version: 5.2.3 OS: Win32 XP SP2
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: tinyunderscoregrasshopper at hotmail dot com
New email:
PHP Version: OS:

 

 [2007-08-25 13:13 UTC] tinyunderscoregrasshopper at hotmail dot com
Description:
------------
I was working on aan abstraction layer for a multi threaded server. It was not till very late I noticed the following strange behaviour:

I let a bunch of client connect. Lets say #1, #2 and #3.
When I disconnect them (not gracefuly) in de backward order (#3, #2 then #1) every thing works as it should be; the 'Close' callback functions are called, and in the right order.

However, when I disconnect them in the same order (#1, #2 then #3) the callback functions will not be called until the last client is closed.

After further testing I noticed that all client closed will only be detected by socket_select if the latter clients are closed.

Reproduce code:
---------------
function Error($error, $desc)
{ echo "Error: $error - $desc\n"; }

function Connect($id)
{ echo "#$id connected.\n"; }

function Close($id)
{ echo "#$id closed.\n"; }

function Receive($id, $msg)
{	echo "#$id said: $msg\n"; }

//------------------------------------------------------------------------------

if (($listener = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == false)
{
	Error("socket_create() failed", socket_strerror($listener));
	exit;
}

socket_set_option($listener, SOL_SOCKET, SO_REUSEADDR, 1); 
socket_set_nonblock($listener);

if (($error = socket_bind($listener, '0.0.0.0', 23)) == false)
{
	Error("socket_bind() failed", socket_strerror($error));
	exit;
}

if (($error = socket_listen($listener, 5)) == false)
{
	Error("socket_listen() failed", socket_strerror($error));
	exit;
}

$sock = array($listener);

//------------------------------------------------------------------------------

for (;;)
{
	$read = $sock;
	socket_select($read, $write = NULL, $except = NULL, NULL);
	
	foreach($read as $socket)
	{
		if ($socket == $listener)
		{
			if (($client = socket_accept($listener)) == false)
			{
				Error("socket_accept() failed", socket_strerror($client));
				continue;
			} else {
				$sock[] = $client;
				$index = intval($client);
				Connect($index);
			}
		} else {
			$bytes = @socket_recv($socket, $input, 512, 0);
			$index = intval($socket);
			if ($bytes == 0)
			{
				if (($key = array_search($socket, $sock)) !== false)
					unset($sock[$key]);
				socket_close($socket);
				Close($index);
			} else {
				Receive($index, $input);
			}
		} 
	}
}

Expected result:
----------------
#5 connected.
#6 connected.
#7 connected.
#5 closed.
#6 closed.
#7 closed.


Actual result:
--------------
#5 connected.
#6 connected.
#7 connected.
#7 closed.
#5 closed.
#6 closed.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-08-25 13:41 UTC] tinyunderscoregrasshopper at hotmail dot com
Nevermind this one. The client I used had tendencies to keep de connection half open.
Sorry for the inconvenience...
 [2007-08-25 20:17 UTC] tinyunderscoregrasshopper at hotmail dot com
nevremind
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 03 12:01:33 2025 UTC