Page 1 of 1

PHP sockets - client socket freezes - bug?

Posted: Fri Apr 24, 2009 5:16 pm
by jeancaffou
I am experiencing a rather strange occurence when working with sockets.

A client socket "freezes" for no aparent reason, and the server socket refuses to read from it, even though the client socket is trying to write to the server socket. On the other hand, the server socket has no problem writing to the client socket and the client reads it, so that means the connection is still established.
What bothers me the most is, that this ACTUALLY happens on localhost connections.

Let me elaborate.

I have a chatserver written in php and a flash client that connects to the php socketserver through the xml socket. I also have a "robot" client written in php.
After some time, for no aparent reason, the server stops reading from a random client socket, and it doesn't matter if it's a php client or flash client. It doesn't even matter if a connection is from a WAN or LAN or localhost.

The server stops reading from it, and all I can do is pinpoint exactly WHERE this happens:
socket_select should return an array of sockets that are ready to read from (1st parameter) but the freezed socket isn't in the array, although it actually is writing to the server (but if the server writes to the frozen socket it works, which is even more weird, because the connection didn't actually drop). So, socket_select after a random period of time ignores a random client socket that is trying to write to the server socket.

Sometimes it takes minutes for this to occur, sometimes days (the time that the client is connected to the server).

After further testing, I discovered that the longer the time span between the server start and client start, the more frequently and quickly this occurs.
For example, if a client is connected to the server almost immediately after the server is started (eg. php server.php & ; php client.php &) this almost never happens. But if a client connects to the server if a server is running for a few days or so, the client socket will be ignored by the server after a few hours or even minutes.

So now i'm wondering - is this a PHP bug or something else?

The "bug" is easily reproduced IMHO, just write a server and client, connect a bunch of clients to it, let them write to the server at a given interval, wait some time and see if anything fails.

<tl;dr>
I'm sorry for the long post, but I'm trying to give as much information as I can, because the problem seems bizzare and insoluble.
</tl;dr>

Re: PHP sockets - client socket freezes - bug?

Posted: Sun May 03, 2009 5:49 pm
by azulgranacrow
i'm so sorry, but i don't have an answer for your problem...

but i'm writing in order to ask you if you could tell me how to connect the php server and the flash app on a hosting... just to connect them, then i'll see how to send what i've to send.

i've been trying to know to make this for almost a month now.. and i'm still have no clue :S

sorry againg!

azulgranaCrow.

Re: PHP sockets - client socket freezes - bug?

Posted: Sun May 03, 2009 6:08 pm
by jeancaffou
1) read these two articles
http://www.adobe.com/devnet/flashplayer ... ty_04.html
http://www.adobe.com/devnet/flashplayer ... files.html
2) write a php server
this might help you out, but be sure to read the php manual for all the functions you don't know
http://dev.kafol.net/2008/11/writing-ch ... n-php.html
3) write a flash client
use xml sockets. it's real easy. read this manual
http://www.adobe.com/support/flash/acti ... ry860.html
here's some actionscript to get you started
http://www.copypastecode.com/codes/view/4983

if your php server works with no problem mentioned above, be sure to post your code here, so i can see what i did wrong

Re: PHP sockets - client socket freezes - bug?

Posted: Sun May 03, 2009 6:19 pm
by azulgranacrow
thank you very much!

i'll read it and then i'll tell you if i could do it work

good luck with your problem.

azulgranaCrow.

Re: PHP sockets - client socket freezes - bug?

Posted: Mon May 04, 2009 2:42 pm
by dml
Hard to tell without knowing how your application protocol works and going through the code line by line.

Can you sketch out the protocol? Clients create a TCP connection, hold it open, send whatever updates they have and receive updates from the server? What happens when a client is finished... do they notify the server that they're finished or do they just shut down the connection?

The first possibility to look at is a resource leak - that the server acquires resources like filehandles for every transaction and doesn't release those resources correctly when the transaction completes. There are per-process limits on filehandles that determine the number of simultaneous connections your server can handle, say it's 64. If your server isn't releasing those filehandle resources correctly, then the kind of thing that happens is that it works correctly, dealing with one or two clients at a time, until the 65th client comes along. Have your server keep a count or a log of connections initiated... does it always crash after the same number? Keep similar counts of anything else significant that your application does, especially things that involve acquiring or using a resource (opening a file, making a database connection, using a web API, etc). Examine your code and ensure that any resource that's acquired is released no matter what path the code takes (in normal web PHP any resource you open is released by the system at the end of the request, but for long-running server processes you have to be more careful). Try to automate multiple client transactions (write a script that starts up 16 or 32 or whatever number of PHP clients) so you can replicate the problem faster and more reliably.

Re: PHP sockets - client socket freezes - bug?

Posted: Mon Aug 24, 2009 1:16 pm
by jeancaffou
I have fixed the bug, although the code seems the same as before.

It seems that I had a problem preparing the socket array, which I would then pass to socket_select().

The bogus socket array caused socket_select() to return one socket less to read. After some testing, I found out that it was always the last entry (by index) in the clients array that got ignored.

The old code is commented. And yes, it took me so long to figure it out. It was kind of weird that localhost connections were dropped due to 'ping timeout' (and relatively soon too! Maybe a few hours, sometimes less) so I had to look into it.

Thanks for your help.

Code: Select all

    /*
    $read[0] = $socket;
    for($i=1;$i<count($clients)+1;$i++) {
        if($clients[$i] != NULL) {
            $read[$i+1] = $clients[$i]['sock'];
        }
    }
    */
    $read[0] = $socket;
    foreach($clients as $i=>$rc) {
        if($i>0) {
            if(isset($rc['sock'])) {
                $read[] = $rc['sock'];
            } else {
                quit($i,'No socket');
            }
        }
    }
    
    $clientsockets = $read;
    $ready = @socket_select($read,$write=NULL,$except=NULL,0,10);
I'm thinking that this was caused, because some faulty unset()-ing of entries in the array. Oh well, foreach loops don't fix THAT bug (bad programming), but at least it goes through the array smoother.