问题
i have a php server listening for 1 c# client.
When a connection is established, it is kept alive until client send command "quit" wich kills the PHP server.
But when the c# client disconnect without the "quit" command (ie : clicking the close (x) button in the windows form) the server just keep listening, and cant receive any other connection from that client.
Is there a way to check from the server side (PHP) if connection is still alive with client.
My php server code is based on exemple1 of : http://php.net/manual/en/sockets.examples.php
If someone is interested in reproducing the bug/error behavior, paste code from exemple1 : http://php.net/manual/en/sockets.examples.php, connect by telnet from a remote client in lan, unplug client wire... php server will hang around forever, no new connection is accepted
(sorry for my poor english)
回答1:
In your loop, you need to check the return value of socket_read(). If it returns FALSE, then there was a read error (which can be caused by the remote host closing the connection). The example code in the link you provided covers this case.
If you need to gracefully handle certain error states, you can always check the socket error code using socket_last_error() -- this note decribes the possible codes.
Edit:
When using putty for telnet, if i close with X button, connecion is closed properly in PHP, but if i unplug the ethernet wire of the putty machine, PHP server just hangs around.
The reason that the connection is closed when killing PuTTY is that PuTTY closes its open connection(s) when exiting. This causes socket_read()
to return with an error code (I believe ECONNRESET
). If you pull the network cable, it doesn't have a chance to do that.
Depending on how your network is configured, the TCP connection should eventually fail. You can attempt to control the timeout by setting SO_RCVTIMEO with socket_set_option(), but this doesn't always work on all platforms (I'm looking at you, WinSock).
Alternatively, you can roll your own polling loop using socket_select() with a reasonable timeout. If none of the connected sockets have data to send after your timeout, then kill the server.
回答2:
The following code will show the state of connection.
$address='example.com';
$port = '9065';
if (isset($port) && ($socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP))
&& (socket_connect($socket, $address, $port))) {
$text='Connection successful on IP $address, port $port';
socket_close($socket);
}
else {
$text='Unable to connect<pre>'.socket_strerror(socket_last_error()).'</pre>';
}
echo $text;
回答3:
I did this by checking if the socket_select()
$read
array includes the connection in question but socket_read()
data is empty (twice).
It seems that socket_select()
adds disconnected clients to the $read
array and socket_read()
gives an empty string ''
when trying to read the disconnected client's data.
来源:https://stackoverflow.com/questions/9793566/php-socket-server-check-if-client-is-alive