|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2007-08-25 13:41 UTC] tinyunderscoregrasshopper at hotmail dot com
[2007-08-25 20:17 UTC] tinyunderscoregrasshopper at hotmail dot com
|
|||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Dec 05 06:00:01 2025 UTC |
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.