我有一个TCP服务器,它侦听传入的消息(数据/请求)并相应地回复。但是,它在第一次连接后没有回复。如果是数据消息,则将数据插入数据库,但确认消息不会到达客户端。并且,如果它是数据请求消息则没有响应。当我重新启动服务器时,它只能正确回复第一个传入连接。从此以后,服务器到客户端都没有响应。 我附上了我的代码,请建议可以采取哪些措施来解决问题。
/**
* Settings
*/
$listen_address = "0.0.0.0";
$listen_port = ****;
$mysql_server = "localhost";
$mysql_username = "root";
$mysql_password = "*****";
$mysql_database = "*****";
/**
* End Settings
*/
function socketError($errorFunction, $die=false) {
$errMsg = socket_strerror(socket_last_error());
echo("{$errorFunction}() error: $errMsg");
if ($die) {
exit();
}
}
function doQuery($query) {
global $db, $mysql_server, $mysql_username, $mysql_password, $mysql_database, $thread_id;
if (0) echo "Trying query: $query\n";
if(!($res = mysqli_query($db, $query))) {
@mysqli_kill($db, $thread_id);
@mysqli_close($db);
$db = mysqli_connect($mysql_server, $mysql_username, $mysql_password, $mysql_database);
if(mysqli_connect_errno()) {
echo("\r\nFailed to connect to MySQL: " . mysqli_connect_error());
}
if(!($res = mysqli_query($db, $query))) {
echo("Error: " . mysqli_error($db) . "\n");
}
}
return $res;
}
function logMessage($socket, $msg) {
global $db, $mysql_server, $mysql_username, $mysql_password, $mysql_database, $thread_id;
$get_ip = socket_getpeername($socket, $address);
echo("Received ({$address}): {$msg}\n");
// process update:<pid>:<sid>! request
// the response is sent in format: d_id:value<uptill the first comma>,
// in case of multiple rows, they are separated by LF character (\n)
if (preg_match('/^update:([0-9]+):([0-9]+)!/', $msg, $matches)) {
$pid = $matches[1];
$sid = $matches[2];
$res = doQuery("SELECT d_id FROM devices WHERE project_id = $pid AND subproject_id = $sid");
if ($res) {
if (mysqli_num_rows($res) > 0) {
$output = '';
$i = 0;
while ($r = mysqli_fetch_array($res)) {
$res2 = doQuery("SELECT tt.d_id, tt.field_a, tt.value FROM data tt INNER JOIN (SELECT d_id, MAX(update_time) AS MaxDateTime FROM data WHERE d_id = {$r['d_id']} GROUP BY d_id) groupedtt ON tt.d_id = groupedtt.d_id AND tt.update_time = groupedtt.MaxDateTime");
if ($res2) {
if (mysqli_num_rows($res2) > 0) {
while ($r2 = mysqli_fetch_array($res2)) {
$tmp = explode(',', $r2['value'], 2);
$output .= ($i>0?"\n":'').$r2['d_id'].':'.$r2['field_a'].':'.$tmp[0].',';
++$i;
}
}
}
}
return $output;
}
}
}
else {
// Ensure nothing breaks our query
$msg = str_replace("'", "\'", $msg);
$parts = explode(':', $msg);
if (is_numeric($parts[0])) {
//if(!mysqli_query($db, "INSERT INTO data (data, datetime, receiver) VALUES ('{$msg}', '".time()."', '".$address."')")) {
doQuery("INSERT INTO data (sender, d_id, value, update_time, field_a) VALUES ('".$address."', {$parts[0]}, '{$parts[2]}', '".date("Y-m-d H:i:s")."','{$parts[1]}')");
return "yes\n";
}
else return "no\n";
}
}
function sendData($socket, $message) {
socket_write($socket, $message);
}
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
ignore_user_abort(true);
// Stage 1: MySQL Connection
$db = mysqli_connect($mysql_server, $mysql_username, $mysql_password, $mysql_database);
if(mysqli_connect_errno()) {
echo("\r\nFailed to connect to MySQL: " . mysqli_connect_error());
}
else
$thread_id = mysqli_thread_id($db);
// Stage 2: start listening
if(!($server = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
socketError("socket_create", true);
}
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
if(!@socket_bind($server, $listen_address, $listen_port)) {
socketError("socket_bind", true);
}
if(!@socket_listen($server)) {
socketError("socket_listen", true);
}
$allSockets = array($server);
echo("Listening on port {$listen_port}\n");
// Stage 3: accept clients
while (true) {
if(connection_aborted()) {
foreach($allSockets as $socket) {
socket_close($socket);
}
break;
}
$changedSockets = $allSockets;
@socket_select($changedSockets, $write = NULL, $except = NULL, 5);
foreach($changedSockets as $socket) {
if ($socket == $server) {
if(!($client = @socket_accept($server))) {
socketError("socket_accept", false);
} else {
$allSockets[] = $client;
}
} else {
$data = socket_read($socket, 2048);
if ($data === false || $data === '') {
unset($allSockets[array_search($socket, $allSockets)]);
socket_close($socket);
} else {
if(trim($data != "")) {
$response = logMessage($socket, $data);
sendData($socket, $response);
}
}
}
}
}
?>