|
@@ -0,0 +1,348 @@
|
|
|
|
+<?php
|
|
|
|
+
|
|
|
|
+namespace App\Console\Commands;
|
|
|
|
+
|
|
|
|
+use App\Jobs\SendDataJob;
|
|
|
|
+use Illuminate\Console\Command;
|
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
|
+use Illuminate\Support\Facades\Redis;
|
|
|
|
+
|
|
|
|
+class ReadCommand extends Command
|
|
|
|
+{
|
|
|
|
+ /**
|
|
|
|
+ * The name and signature of the console command.
|
|
|
|
+ *
|
|
|
|
+ * @var string
|
|
|
|
+ */
|
|
|
|
+ protected $signature = 'command:readTXT';
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The console command description.
|
|
|
|
+ *
|
|
|
|
+ * @var string
|
|
|
|
+ */
|
|
|
|
+ protected $description = '读取文件';
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Create a new command instance.
|
|
|
|
+ *
|
|
|
|
+ * @return void
|
|
|
|
+ */
|
|
|
|
+ public function __construct()
|
|
|
|
+ {
|
|
|
|
+ parent::__construct();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Execute the console command.
|
|
|
|
+ *
|
|
|
|
+ * @return mixed
|
|
|
|
+ */
|
|
|
|
+ public function handle()
|
|
|
|
+ {
|
|
|
|
+// $this->readTxtForData();
|
|
|
|
+ $this->tcpServer();
|
|
|
|
+ $this->info('Your command executed!');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //读取数据
|
|
|
|
+ public function readTxtForData()
|
|
|
|
+ {
|
|
|
|
+ $directory = env('PROCESS_DIR',null);
|
|
|
|
+ if(! $directory) {
|
|
|
|
+ echo '未找到日志文件位置,请确认工具运行位置,再进行配置!';die;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $newLogFile = storage_path().'/app/public/record_device.txt';
|
|
|
|
+// $positionFile = storage_path().'/app/public/position_device.txt';
|
|
|
|
+
|
|
|
|
+ date_default_timezone_set("PRC");
|
|
|
|
+ $key = date("Y-m-d",time());
|
|
|
|
+ $position = Cache::get($key);
|
|
|
|
+
|
|
|
|
+ // 读取上次记录的位置
|
|
|
|
+ $lastPosition = 0;
|
|
|
|
+ if ($position) $lastPosition = $position;
|
|
|
|
+// if (file_exists($positionFile)) {
|
|
|
|
+// $lastPosition = intval(file_get_contents($positionFile));
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ // 持续监视日志文件的变化
|
|
|
|
+ while (true) {
|
|
|
|
+ $key = date("Y-m-d",time());
|
|
|
|
+
|
|
|
|
+ //日志源 文件位置
|
|
|
|
+ $logFile = $directory . "/TesttoolLog" . $key . '.log';
|
|
|
|
+
|
|
|
|
+ // 检查文件是否有更新
|
|
|
|
+ clearstatcache(true, $logFile);
|
|
|
|
+ $currentFileSize = filesize($logFile);
|
|
|
|
+
|
|
|
|
+ echo "当前指针位置:$currentFileSize 上一次指针位置:$lastPosition \n";
|
|
|
|
+
|
|
|
|
+ if ($currentFileSize > $lastPosition) {
|
|
|
|
+ // 打开原始日志文件和新的日志文件
|
|
|
|
+ $fileHandle = fopen($logFile, 'r');
|
|
|
|
+ $newFileHandle = fopen($newLogFile, 'a'); // 使用追加模式打开新的日志文件
|
|
|
|
+
|
|
|
|
+ // 移动文件指针到上次记录的位置
|
|
|
|
+ fseek($fileHandle, $lastPosition);
|
|
|
|
+
|
|
|
|
+ // 逐行读取并处理新增内容
|
|
|
|
+ $read_data = [];
|
|
|
|
+ while (($line = fgets($fileHandle)) !== false) {
|
|
|
|
+ // 提取Tag数字
|
|
|
|
+ $pattern = '/Tag:(\d+)/';
|
|
|
|
+ preg_match($pattern, $line, $matches);
|
|
|
|
+
|
|
|
|
+ if (isset($matches[1])) {
|
|
|
|
+ $tagNumber = $matches[1];
|
|
|
|
+ echo "接收到的数据:" . $tagNumber . "\n";
|
|
|
|
+
|
|
|
|
+ $read_data[] = $tagNumber;
|
|
|
|
+ // 将Tag数字写入新的日志文件
|
|
|
|
+ fwrite($newFileHandle, $tagNumber . PHP_EOL);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(! empty($read_data)) {
|
|
|
|
+ $this->sendData($read_data);
|
|
|
|
+ echo '发送成功---!' . "\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取新的位置并更新位置文件
|
|
|
|
+ $lastPosition = ftell($fileHandle);
|
|
|
|
+ Cache::put($key,$lastPosition,86400);
|
|
|
|
+// file_put_contents($positionFile, $lastPosition);
|
|
|
|
+
|
|
|
|
+ // 关闭文件句柄
|
|
|
|
+ fclose($fileHandle);
|
|
|
|
+ fclose($newFileHandle);
|
|
|
|
+ } else {
|
|
|
|
+ echo '暂无新数据...' . "\n";
|
|
|
|
+ // 在下一次检查之前休眠一段时间
|
|
|
|
+ sleep(2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function sendData($data){
|
|
|
|
+ $url = env('CLOUD_ADDRESS',null);
|
|
|
|
+
|
|
|
|
+ if(empty($url)) return;
|
|
|
|
+
|
|
|
|
+ $curl = curl_init();
|
|
|
|
+ curl_setopt_array($curl, array(
|
|
|
|
+ CURLOPT_URL => $url,
|
|
|
|
+ CURLOPT_RETURNTRANSFER => true,
|
|
|
|
+ CURLOPT_ENCODING => '',
|
|
|
|
+ CURLOPT_MAXREDIRS => 10,
|
|
|
|
+ CURLOPT_TIMEOUT => 0,
|
|
|
|
+ CURLOPT_FOLLOWLOCATION => true,
|
|
|
|
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
|
|
+ CURLOPT_CUSTOMREQUEST => 'POST',
|
|
|
|
+ CURLOPT_POSTFIELDS => $data,
|
|
|
|
+ ));
|
|
|
|
+ $response = curl_exec($curl);
|
|
|
|
+ curl_close($curl);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function tcpServer(){
|
|
|
|
+ $host = env('HOST_TCP',null); // 主机地址 $_SERVER['REMOTE_ADDR']; 局域网内ip地址
|
|
|
|
+ $port = env('HOST_PORT',null); // 端口号
|
|
|
|
+
|
|
|
|
+ // 创建一个TCP socket
|
|
|
|
+ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
|
|
+ // 绑定到指定的主机和端口
|
|
|
|
+ socket_bind($socket, $host, $port);
|
|
|
|
+ // 监听连接
|
|
|
|
+ socket_listen($socket);
|
|
|
|
+
|
|
|
|
+ // 初始内存使用量
|
|
|
|
+ $initialMemoryUsage = memory_get_usage();
|
|
|
|
+
|
|
|
|
+ echo date("Y-m-d H:i:s") . "服务器已启动\n";
|
|
|
|
+ file_put_contents('C:\Users\Administrator\Desktop\record.txt',date("Y-m-d H:i:s") . "服务器已启动".PHP_EOL,8);
|
|
|
|
+
|
|
|
|
+ while (true) {
|
|
|
|
+ // 接受连接请求并创建新的套接字
|
|
|
|
+ $clientSocket = socket_accept($socket);
|
|
|
|
+
|
|
|
|
+ if ($clientSocket === false) {
|
|
|
|
+ // 错误处理
|
|
|
|
+ $error = socket_strerror(socket_last_error($socket));
|
|
|
|
+ echo "接受连接请求失败:{$error}\n";
|
|
|
|
+ continue; // 继续下一次循环
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 读取客户端发送的数据
|
|
|
|
+ $data = socket_read($clientSocket, 1024);
|
|
|
|
+ // 其他操作...
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
+ // 异常处理
|
|
|
|
+ echo date("Y-m-d H:i:s") . "捕获到异常:{$e->getMessage()}\n";
|
|
|
|
+ continue; // 继续下一次循环
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// file_put_contents('C:\Users\Administrator\Desktop\record2.txt',$data .PHP_EOL,8);
|
|
|
|
+
|
|
|
|
+ $this->byteParsing3($data);
|
|
|
|
+
|
|
|
|
+ // 发送响应给客户端
|
|
|
|
+// $response = "服务器已接收到您的消息:" . $data;
|
|
|
|
+// socket_write($clientSocket, $response, strlen($response));
|
|
|
|
+
|
|
|
|
+ $currentMemoryUsage = memory_get_usage();
|
|
|
|
+ $memoryDiff = $currentMemoryUsage - $initialMemoryUsage;
|
|
|
|
+
|
|
|
|
+ echo "内存使用量变化:" . $memoryDiff . " 字节\n";
|
|
|
|
+
|
|
|
|
+ $initialMemoryUsage = $currentMemoryUsage;
|
|
|
|
+
|
|
|
|
+ // 关闭当前连接的套接字
|
|
|
|
+ socket_close($clientSocket);
|
|
|
|
+
|
|
|
|
+ gc_collect_cycles();
|
|
|
|
+
|
|
|
|
+ sleep(5);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 关闭服务器套接字
|
|
|
|
+ socket_close($socket);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function byteParsing2($data){
|
|
|
|
+ $frame = $data;
|
|
|
|
+ // 提取字段值
|
|
|
|
+ $frameHeader = bin2hex(substr($frame, 0, 2));
|
|
|
|
+ $frameLength = unpack('v', substr($frame, 2, 2))[1];
|
|
|
|
+ $frameSequence = unpack('v', substr($frame, 4, 2))[1];
|
|
|
|
+ $port = ord(substr($frame, 6, 1));
|
|
|
|
+ $communicationType = unpack('v', substr($frame, 7, 2))[1];
|
|
|
|
+ $payload = substr($frame, 9, $frameLength - 8);
|
|
|
|
+ $checksum = ord(substr($frame, -3, 1));
|
|
|
|
+ $frameTail = bin2hex(substr($frame, -2));
|
|
|
|
+
|
|
|
|
+ $payloadBytes = substr($frame, 9, 4); // 假设帧载荷在通信帧中的偏移量为9,并且长度为4个字节
|
|
|
|
+
|
|
|
|
+// 将4个字节转换为无符号整数(根据您的数据编码方式确定是否需要使用符号整数)
|
|
|
|
+ $payloadValue = unpack('N', $payloadBytes)[1];
|
|
|
|
+ echo "zhen" . $payloadValue . "\n";
|
|
|
|
+ $payloadHex = sprintf('%08X', $payloadValue);
|
|
|
|
+
|
|
|
|
+ echo "帧载荷值: $payloadHex\n";
|
|
|
|
+
|
|
|
|
+ // 打印字段值
|
|
|
|
+ echo "帧头: $frameHeader\n";
|
|
|
|
+ echo "帧长度: $frameLength\n";
|
|
|
|
+ echo "帧序号: $frameSequence\n";
|
|
|
|
+ echo "端口: $port\n";
|
|
|
|
+ echo "通信类型: $communicationType\n";
|
|
|
|
+ echo "帧载荷: $payload\n";
|
|
|
|
+ echo "校验和: $checksum\n";
|
|
|
|
+ echo "帧尾: $frameTail\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function byteParsing($data){
|
|
|
|
+ // 接收到的TCP数据(以字节形式表示)
|
|
|
|
+ $tcpData = $data;
|
|
|
|
+ // 解析源端口和目标端口
|
|
|
|
+ $sourcePort = unpack('n', substr($tcpData, 0, 2))[1];
|
|
|
|
+ $destinationPort = unpack('n', substr($tcpData, 2, 2))[1];
|
|
|
|
+ // 解析其他TCP头部字段,解析序列号
|
|
|
|
+ $sequenceNumber = unpack('N', substr($tcpData, 4, 4))[1];
|
|
|
|
+
|
|
|
|
+ // 获取TCP头部长度(通过读取数据偏移计算得出)
|
|
|
|
+ $dataOffset = ord(substr($tcpData, 12, 1)) >> 4;
|
|
|
|
+ $headerLength = $dataOffset * 4;
|
|
|
|
+
|
|
|
|
+ // 提取数据部分
|
|
|
|
+ $data = substr($tcpData, $headerLength);
|
|
|
|
+
|
|
|
|
+ // 处理数据部分中的控制字符
|
|
|
|
+ $data = $this->removeControlCharacters($data);
|
|
|
|
+
|
|
|
|
+ // 打印解析结果
|
|
|
|
+ echo "源端口: $sourcePort\n";
|
|
|
|
+ echo "目标端口: $destinationPort\n";
|
|
|
|
+ echo "序列号: $sequenceNumber\n";
|
|
|
|
+ if(! empty($data)){
|
|
|
|
+ echo "数据: $data\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 去除控制字符的函数
|
|
|
|
+ function removeControlCharacters($string) {
|
|
|
|
+ $controlChars = array(
|
|
|
|
+ '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', // 去除 ASCII 控制字符
|
|
|
|
+// '/\xEF\xBF\xBD/u' // 去除 UTF-8 中的替代字符
|
|
|
|
+ );
|
|
|
|
+ return preg_replace($controlChars, '', $string);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function readTxt(){
|
|
|
|
+ $directory = env('PROCESS_DIR',null);
|
|
|
|
+ $directory = 'C:\Users\Administrator\Desktop\\'; // 替换为你的文件所在目录路径
|
|
|
|
+ $currentDate = date('Y-m-d'); // 当前日期
|
|
|
|
+ $file = $directory . "TesttoolLog" . $currentDate . '.log'; // 拼接文件路径和文件名
|
|
|
|
+
|
|
|
|
+ $lastModified = filemtime($file); // 获取文件最后修改时间
|
|
|
|
+
|
|
|
|
+ while (true) {
|
|
|
|
+ clearstatcache(); // 清除文件状态缓存
|
|
|
|
+ $currentDate = date('Y-m-d'); // 获取当前日期
|
|
|
|
+ $currentFile = $directory . "TesttoolLog" . $currentDate . '.log'; // 当前日期对应的文件路径和文件名
|
|
|
|
+
|
|
|
|
+ if ($file !== $currentFile) {
|
|
|
|
+ // 文件已切换,更新文件路径和最后修改时间
|
|
|
|
+ $file = $currentFile;
|
|
|
|
+ $lastModified = filemtime($file);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $currentModified = filemtime($file); // 获取当前文件最后修改时间
|
|
|
|
+
|
|
|
|
+ if ($currentModified > $lastModified) {
|
|
|
|
+ // 文件已被修改,读取新增内容
|
|
|
|
+ $handle = fopen($file, 'r');
|
|
|
|
+ fseek($handle, -1, SEEK_END); // 定位到文件末尾前两个字节
|
|
|
|
+ $data = fread($handle, 2); // 读取新增内容
|
|
|
|
+ fclose($handle);
|
|
|
|
+
|
|
|
|
+ // 处理新增内容
|
|
|
|
+ // ...
|
|
|
|
+
|
|
|
|
+ // 示例:打印新增内容
|
|
|
|
+ echo $data;
|
|
|
|
+
|
|
|
|
+ $lastModified = $currentModified; // 更新最后修改时间
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sleep(1); // 睡眠一段时间后再次检查文件是否被修改
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function byteParsing3($data){
|
|
|
|
+ $hexData = bin2hex($data);
|
|
|
|
+ $hexData = str_replace(' ', '', $hexData);
|
|
|
|
+ $toReplace = array("a6a8001300000a00010101001708120012000103b5a5a7", "a6a8000c00000a0003120001037da5a7");
|
|
|
|
+ $result = str_replace($toReplace, "", $hexData);
|
|
|
|
+// echo "原数据:" . $hexData . PHP_EOL;
|
|
|
|
+// $memoryUsage = memory_get_usage();
|
|
|
|
+// echo "当前脚本占用的内存量:".$memoryUsage." 字节" . "\n";
|
|
|
|
+//
|
|
|
|
+// $memoryUsage = memory_get_peak_usage();
|
|
|
|
+// echo "PHP程序总内存使用量:" . $memoryUsage . " 字节" . "\n";
|
|
|
|
+
|
|
|
|
+ if($result){
|
|
|
|
+ $last38Chars = substr($result, -38, 32);
|
|
|
|
+ echo "替换后:" . $last38Chars . PHP_EOL;
|
|
|
|
+
|
|
|
|
+ file_put_contents('C:\Users\Administrator\Desktop\record.txt',$last38Chars.PHP_EOL,8);
|
|
|
|
+ if(! empty($last38Chars)) {
|
|
|
|
+ $this->sendData([$last38Chars]);
|
|
|
|
+ echo '发送成功---!' . "\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|