I created a PHP Socket Server with PHP_NORMAL_READ mode. So, a message to the server is read when it ends with \n or \r. I tried it by connecting to the server with multiple telnet instances, and it works great.
我用PHP_NORMAL_READ模式创建了一个PHP套接字服务器。因此,当以\ n或\ r结尾时,将读取到服务器的消息。我通过连接到具有多个telnet实例的服务器来尝试它,并且它工作得很好。
However, when I connect to the server with 1 flash application and 1 telnet application (I first start the flash one), the flash one seems to make the server hang - the server is getting stuck somewhere and no longer receiving data from eg. the telnet client.
但是,当我连接到具有1个闪存应用程序和1个telnet应用程序的服务器时(我首先启动闪存),闪存似乎使服务器挂起 - 服务器卡在某处,不再接收来自例如的数据。 telnet客户端。
Because anyone can code a flash client, this has to be fixed server side. The server's code:
因为任何人都可以编写Flash客户端代码,这必须是固定服务器端。服务器的代码:
<?php
// config
$timelimit = 60; // amount of seconds the server should run for, 0 = run indefintely
$port = 9000; // the port to listen on
$address = $_SERVER['SERVER_ADDR']; // the server's external IP
$backlog = SOMAXCONN; // the maximum of backlog incoming connections that will be queued for processing
// configure custom PHP settings
error_reporting(1); // report all errors
ini_set('display_errors', 1); // display all errors
set_time_limit($timelimit); // timeout after x seconds
ob_implicit_flush(); // results in a flush operation after every output call
//create master IPv4 based TCP socket
if (!($master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) die("Could not create master socket, error: ".socket_strerror(socket_last_error()));
// set socket options (local addresses can be reused)
if (!socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)) die("Could not set socket options, error: ".socket_strerror(socket_last_error()));
// bind to socket server
if (!socket_bind($master, $address, $port)) die("Could not bind to socket server, error: ".socket_strerror(socket_last_error()));
// start listening
if (!socket_listen($master, $backlog)) die("Could not start listening to socket, error: ".socket_strerror(socket_last_error()));
//display startup information
echo "[".date('Y-m-d H:i:s')."] SERVER CREATED (MAXCONN: ".SOMAXCONN.").\n"; //max connections is a kernel variable and can be adjusted with sysctl
echo "[".date('Y-m-d H:i:s')."] Listening on ".$address.":".$port.".\n";
$time = time(); //set startup timestamp
// init read sockets array
$read_sockets = array($master);
// continuously handle incoming socket messages, or close if time limit has been reached
while ((!$timelimit) or (time() - $time < $timelimit)) {
$changed_sockets = $read_sockets;
socket_select($changed_sockets, $write = null, $except = null, null);
foreach($changed_sockets as $socket) {
if ($socket == $master) {
if (($client = socket_accept($master)) < 0) {
continue;
} else {
array_push($read_sockets, $client);
}
} else {
$data = @socket_read($socket, 1024, PHP_NORMAL_READ); //read a maximum of 1024 bytes until a new line has been sent
if ($data === false) { //the client disconnected
$index = array_search($socket, $read_sockets);
unset($read_sockets[$index]);
socket_close($socket);
} elseif ($data = trim($data)) { //remove whitespace and continue only if the message is not empty
echo "we received: ".$data."\n\n";
//handleData($data, $socket);
}
}
}
}
socket_close($master); //close the socket
echo "[".date('Y-m-d H:i:s')."] SERVER CLOSED.\n";
//function to write to the flash client
function flash_write($socket, $msg) {
socket_write($socket, $msg.chr(0x0));
}
?>
Does anyone know what may cause this? I tried changing the timeout on the socket_select from none to 0 (instant return), but that didn't seem to change anything.
有谁知道可能导致这种情况的原因?我尝试将socket_select上的超时从none更改为0(即时返回),但这似乎没有改变任何东西。
2 个解决方案
#1
Could you post the source of the flash client? That would show what the problem is?
你可以发布Flash客户端的来源吗?这会显示问题是什么?
Are you sure the last thing you send from the flash client is a \n ?
您确定从Flash客户端发送的最后一件事是\ n吗?
Otherwise the server would block on socket_read() as the flash client socket can be read without blocking (triggered socket_select()), but doesn't send the ending \n.
否则服务器将阻塞socket_read(),因为可以在不阻塞的情况下读取闪存客户端套接字(触发socket_select()),但不发送结尾\ n。
#2
One thing to help you debug: error_reporting(1) does not enable the display of all errors. Look at the documentation at http://us3.php.net/manual/en/function.error-reporting.php. You need something like error_reporting(E_ALL).
有一点可以帮助您调试:error_reporting(1)不会显示所有错误。请查看http://us3.php.net/manual/en/function.error-reporting.php上的文档。你需要像error_reporting(E_ALL)这样的东西。
#1
Could you post the source of the flash client? That would show what the problem is?
你可以发布Flash客户端的来源吗?这会显示问题是什么?
Are you sure the last thing you send from the flash client is a \n ?
您确定从Flash客户端发送的最后一件事是\ n吗?
Otherwise the server would block on socket_read() as the flash client socket can be read without blocking (triggered socket_select()), but doesn't send the ending \n.
否则服务器将阻塞socket_read(),因为可以在不阻塞的情况下读取闪存客户端套接字(触发socket_select()),但不发送结尾\ n。
#2
One thing to help you debug: error_reporting(1) does not enable the display of all errors. Look at the documentation at http://us3.php.net/manual/en/function.error-reporting.php. You need something like error_reporting(E_ALL).
有一点可以帮助您调试:error_reporting(1)不会显示所有错误。请查看http://us3.php.net/manual/en/function.error-reporting.php上的文档。你需要像error_reporting(E_ALL)这样的东西。