使用 PHP 个套接字向多个客户端发送和接收数据
Sending and receiving data to multiple clients using PHP Sockets
我正在使用 SocketServer.class.php 从我的服务器接收和发送数据给远程客户端。它仅适用于一个客户。
客户端是一个数字仪表,它使用连接到它的 GPRS 调制解调器通过 TCP/IP 发送数据。每个仪表使用其仪表 ID 进行区分,范围从 1 到 247,数据以 ASCII 格式传递和接收。
PHP 代码是 运行 windows 命令 shell 并将输入读数保存到数据库中。
现在,当尝试对 ID 为 1 和 2 的两个仪表执行相同操作时,它不起作用。我不知道如何进行。我附上我到目前为止执行的代码。
<?php
require_once("SocketServer.class.php"); // Include the File
$server = new SocketServer("192.168.1.5",5001); // Create a Server binding to the given ip address and listen to port 5001for connections
$server->max_clients = 247; // Allow no more than 247 people to connect at a time
$server->hook("CONNECT","handle_connect"); // Run handle_connect every time someone connects
$server->hook("INPUT","handle_input");// Run handle_input whenever text is sent to the server
/* //main loop
for($i=1; $i<=247; $i++) {
}*/
$server->infinite_loop(); // Run Server Code Until Process is terminated.*/
/*$server -> loop_once();*/
function handle_connect(&$server,&$client,$input)
{
SocketServer::socket_write_smart($client->socket,"String","");
}
function handle_input($server,&$client,$input)
{
// You probably want to sanitize your inputs here
$trim = trim($input); // Trim the input, Remove Line Endings and Extra Whitespace.
saveInput($input); // this function would save the values to database as it is received
$output = "65030063002F"; //65 -> Meter ID 101 in HEX 03 -> function 0063 -> start register 002F -> Number of registers
$hexad = hexToStr($output);
$hexad .= crc16($hexad);
echo $hexad;
SocketServer::socket_write_smart($client->socket,&$hexad,"");
}
function saveInput($input)
{
$res = strToHex($input);
for ($i=0; $i < strlen($res)-1; $i+=2)
{
$string[] = $res[$i].$res[$i+1];
}
if(hexdec($string[0]) > 0 && hexdec($string[0]) < 248) {
echo "Meter --> ".hexdec($string[0])."<br>";
echo "Function --> ".hexdec($string[1])."<br>";
$byte = hexdec($string[2]);
echo "Byte Count --> ".$byte."<br>";
/* $l=40100;
for($k=3; $k<($byte+3); $k+=2) {
echo "Register $l --> ".hexdec($string[$k].$string[$k+1])."<br>";
$l++;
}*/
echo "<br>";
}
}
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
function strToHex($string)
{
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= str_pad(dechex(ord($string[$i])),2,"0",STR_PAD_LEFT);
}
$hex = trim($hex);
return $hex;
}
function crc16($data)
{
$crc = 0xFFFF;
for ($i = 0; $i < strlen($data); $i++)
{
$crc ^=ord($data[$i]);
for ($j = 8; $j !=0; $j--)
{
if (($crc & 0x0001) !=0)
{
$crc >>= 1;
$crc ^= 0xA001;
}
else
$crc >>= 1;
}
}
$crc = dechex($crc);
$order = str_split($crc, 2);
$order = array_reverse($order);
$crc = implode($order);
$crc = hexToStr($crc);
return $crc;
}
?>
return 值全部以十六进制存储。有没有更好的方法来做到这一点。
我想发送 65030063002FFC2C
作为 meter 101
的输入,并将 66030063002FFC1F
作为 id 为“102”的 meter 的输入,依此类推。只有当仪表 ID 在仪表输入端匹配时,它才会 return 将相应的读数发送到服务器。这么多天以来,我一直在努力解决这个问题,但由于我是 PHP 套接字的新手,并且对它知之甚少,所以很难。
由于还没有人回答,我进行了一些挖掘并找到了解决方法。但它包括一个循环。所以有几米。我可以使用套接字写入和 for 循环将数据发送到仪表。没有使上述代码工作的部分是在发送 100 秒的请求数据包时,它实际上接收到前 8 个字节并拒绝其余字节。所以我用 sleep(1) 添加了一个延迟,代码像 charm
我正在使用 SocketServer.class.php 从我的服务器接收和发送数据给远程客户端。它仅适用于一个客户。 客户端是一个数字仪表,它使用连接到它的 GPRS 调制解调器通过 TCP/IP 发送数据。每个仪表使用其仪表 ID 进行区分,范围从 1 到 247,数据以 ASCII 格式传递和接收。 PHP 代码是 运行 windows 命令 shell 并将输入读数保存到数据库中。 现在,当尝试对 ID 为 1 和 2 的两个仪表执行相同操作时,它不起作用。我不知道如何进行。我附上我到目前为止执行的代码。
<?php
require_once("SocketServer.class.php"); // Include the File
$server = new SocketServer("192.168.1.5",5001); // Create a Server binding to the given ip address and listen to port 5001for connections
$server->max_clients = 247; // Allow no more than 247 people to connect at a time
$server->hook("CONNECT","handle_connect"); // Run handle_connect every time someone connects
$server->hook("INPUT","handle_input");// Run handle_input whenever text is sent to the server
/* //main loop
for($i=1; $i<=247; $i++) {
}*/
$server->infinite_loop(); // Run Server Code Until Process is terminated.*/
/*$server -> loop_once();*/
function handle_connect(&$server,&$client,$input)
{
SocketServer::socket_write_smart($client->socket,"String","");
}
function handle_input($server,&$client,$input)
{
// You probably want to sanitize your inputs here
$trim = trim($input); // Trim the input, Remove Line Endings and Extra Whitespace.
saveInput($input); // this function would save the values to database as it is received
$output = "65030063002F"; //65 -> Meter ID 101 in HEX 03 -> function 0063 -> start register 002F -> Number of registers
$hexad = hexToStr($output);
$hexad .= crc16($hexad);
echo $hexad;
SocketServer::socket_write_smart($client->socket,&$hexad,"");
}
function saveInput($input)
{
$res = strToHex($input);
for ($i=0; $i < strlen($res)-1; $i+=2)
{
$string[] = $res[$i].$res[$i+1];
}
if(hexdec($string[0]) > 0 && hexdec($string[0]) < 248) {
echo "Meter --> ".hexdec($string[0])."<br>";
echo "Function --> ".hexdec($string[1])."<br>";
$byte = hexdec($string[2]);
echo "Byte Count --> ".$byte."<br>";
/* $l=40100;
for($k=3; $k<($byte+3); $k+=2) {
echo "Register $l --> ".hexdec($string[$k].$string[$k+1])."<br>";
$l++;
}*/
echo "<br>";
}
}
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
function strToHex($string)
{
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= str_pad(dechex(ord($string[$i])),2,"0",STR_PAD_LEFT);
}
$hex = trim($hex);
return $hex;
}
function crc16($data)
{
$crc = 0xFFFF;
for ($i = 0; $i < strlen($data); $i++)
{
$crc ^=ord($data[$i]);
for ($j = 8; $j !=0; $j--)
{
if (($crc & 0x0001) !=0)
{
$crc >>= 1;
$crc ^= 0xA001;
}
else
$crc >>= 1;
}
}
$crc = dechex($crc);
$order = str_split($crc, 2);
$order = array_reverse($order);
$crc = implode($order);
$crc = hexToStr($crc);
return $crc;
}
?>
return 值全部以十六进制存储。有没有更好的方法来做到这一点。
我想发送 65030063002FFC2C
作为 meter 101
的输入,并将 66030063002FFC1F
作为 id 为“102”的 meter 的输入,依此类推。只有当仪表 ID 在仪表输入端匹配时,它才会 return 将相应的读数发送到服务器。这么多天以来,我一直在努力解决这个问题,但由于我是 PHP 套接字的新手,并且对它知之甚少,所以很难。
由于还没有人回答,我进行了一些挖掘并找到了解决方法。但它包括一个循环。所以有几米。我可以使用套接字写入和 for 循环将数据发送到仪表。没有使上述代码工作的部分是在发送 100 秒的请求数据包时,它实际上接收到前 8 个字节并拒绝其余字节。所以我用 sleep(1) 添加了一个延迟,代码像 charm