TcpServer.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. #include "TcpServer.h"
  2. #include <time.h>
  3. #include <nlohmann/json.hpp>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <hiredis/hiredis.h>
  8. #include <sqlite3.h>
  9. #include "DatabaseWorker.h"
  10. #include "../logger/Logger.h"
  11. // 回调函数,用于处理查询结果
  12. static int sql_callback(void *NotUsed, int argc, char **argv, char **azColName) {
  13. for (int i = 0; i < argc; i++) {
  14. printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  15. }
  16. printf("\n");
  17. return 0;
  18. }
  19. // 计算CRC16的表格(预先计算以提高效率)
  20. static uint16_t crc16_table[256];
  21. // 初始化CRC16表格
  22. static void init_crc16_table() {
  23. uint16_t polynomial = 0xA001;
  24. for (uint16_t i = 0; i < 256; i++) {
  25. uint16_t crc = i;
  26. for (uint8_t j = 0; j < 8; j++) {
  27. if (crc & 0x0001) {
  28. crc = (crc >> 1) ^ polynomial;
  29. } else {
  30. crc >>= 1;
  31. }
  32. }
  33. crc16_table[i] = crc;
  34. }
  35. }
  36. // 计算给定数据缓冲区的CRC16校验值
  37. static uint16_t calculate_crc16(uint8_t *data, size_t length) {
  38. uint16_t crc = 0xFFFF; // 初始值
  39. for (size_t i = 0; i < length; i++) {
  40. uint8_t table_index = (crc ^ data[i]) & 0xFF;
  41. crc = (crc >> 8) ^ crc16_table[table_index];
  42. }
  43. return crc;
  44. }
  45. // 构造函数
  46. TcpServer::TcpServer(int port)
  47. :
  48. db_queue(), // 默认构造 db_queue
  49. db_worker(db_queue), // 用 db_queue 初始化 db_worker
  50. running(true),
  51. conn_num(0)
  52. {
  53. server_fd = socket(AF_INET, SOCK_STREAM, 0);
  54. if (server_fd < 0) {
  55. perror("Socket creation failed");
  56. throw std::runtime_error("Socket creation failed");
  57. }
  58. address.sin_family = AF_INET;
  59. address.sin_addr.s_addr = INADDR_ANY;
  60. address.sin_port = htons(port);
  61. addrlen = sizeof(address);
  62. int opt = 1;
  63. // Set socket options
  64. if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
  65. perror("Setsockopt failed");
  66. std::cout << "port = " << port << std::endl;
  67. close(server_fd);
  68. throw std::runtime_error("Setsockopt failed");
  69. }
  70. // Bind socket to address
  71. if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
  72. perror("Bind failed");
  73. close(server_fd);
  74. throw std::runtime_error("Bind failed");
  75. }
  76. // Listen for incoming connections
  77. if (listen(server_fd, SOMAXCONN) < 0) {
  78. perror("Listen failed");
  79. close(server_fd);
  80. throw std::runtime_error("Listen failed");
  81. }
  82. std::cout << "Server listening on port " << port << std::endl;
  83. }
  84. // 析构函数
  85. TcpServer::~TcpServer() {
  86. running = false;
  87. if (accept_thread.joinable()) {
  88. accept_thread.join();
  89. }
  90. for (auto &th : threads) {
  91. if (th.joinable()) {
  92. th.join();
  93. }
  94. }
  95. close(server_fd);
  96. }
  97. // 启动服务器
  98. void TcpServer::start_server() {
  99. std::cout << "Starting server..." << std::endl;
  100. // 初始化CRC16表格
  101. init_crc16_table();
  102. accept_thread = std::thread([this]() {
  103. while (this->running) {
  104. char client_ip[INET_ADDRSTRLEN];
  105. int new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
  106. if (new_socket < 0) {
  107. // 打印错误信息
  108. std::cerr << "Accept failed with error: " << strerror(errno) << std::endl;
  109. std::cout << "当前连接数量: " << this->conn_num << std::endl;
  110. if (errno == EINTR) {
  111. // 如果是信号中断,继续等待连接
  112. continue;
  113. } else {
  114. // 其他错误,继续等待连接
  115. continue;
  116. }
  117. }
  118. // 获取客户端 IP 和端口
  119. inet_ntop(AF_INET, &(address.sin_addr), client_ip, INET_ADDRSTRLEN);
  120. int client_port = ntohs(address.sin_port);
  121. std::string ip_str(client_ip);
  122. std::cout << "客户端已连接: " << ip_str << ":" << client_port << std::endl;
  123. {
  124. std::lock_guard<std::mutex> lock(mtx_client_addrs);
  125. if (ip_str == "172.16.111.60" || ip_str == "172.16.111.61" || ip_str == "172.16.111.62") {
  126. for (auto it = client_addrs.begin(); it != client_addrs.end();) {
  127. if (it->ip == ip_str) {
  128. it = client_addrs.erase(it); // 删除当前元素,返回下一个迭代器
  129. } else {
  130. ++it; // 不删,继续往后走
  131. }
  132. }
  133. }
  134. client_addrs.push_back({ip_str, client_port, new_socket});
  135. }
  136. {
  137. std::lock_guard<std::mutex> lock(mtx);
  138. this->conn_num++;
  139. LOG_Debug("客户端已连接:%s %d 当前连接数量:%d", ip_str.c_str(), client_port, this->conn_num);
  140. std::cout << "当前连接数量: " << this->conn_num << std::endl;
  141. // LOG_Debug("", this->conn_num); // 不会输出
  142. }
  143. threads.emplace_back([this, new_socket, ip_str]() {
  144. handle_client(new_socket, ip_str);
  145. });
  146. // std::thread(&TcpServer::handle_client, this, new_socket).detach();
  147. }
  148. });
  149. accept_thread.detach(); // 让接受线程独立运行
  150. // accept_thread.join();
  151. }
  152. std::vector<ClientAddr> TcpServer::get_connected_clients() {
  153. std::lock_guard<std::mutex> lock(mtx_client_addrs);
  154. return client_addrs;
  155. }
  156. void TcpServer::remove_connected_clients(std::string ip) {
  157. std::lock_guard<std::mutex> lock(mtx_client_addrs);
  158. auto it = client_addrs.begin();
  159. while (it != client_addrs.end()) {
  160. if (it->ip == ip) {
  161. // close(it->sockfd); // 关闭 socket
  162. it = client_addrs.erase(it); // 删除元素并更新迭代器
  163. } else {
  164. ++it;
  165. }
  166. }
  167. }
  168. nlohmann::json decode_modbus_msg(const uint8_t * buffer, std::string& device_name){
  169. int dev_addr = buffer[0];
  170. int fun_code = buffer[1];
  171. int data_len = buffer[2];
  172. int dev_type = buffer[6];
  173. nlohmann::json json_save;
  174. if(dev_type == 9) {
  175. std::cout << "门锁" << std::endl;
  176. }
  177. if(dev_type == 10) {
  178. std::cout << "噪声" << std::endl;
  179. }
  180. if(dev_type == 12) {
  181. std::cout << "蓄电池" << std::endl;
  182. }
  183. std::string postfix = "NARI-";
  184. // 公共字段
  185. json_save["status"] = "run";
  186. json_save["gateway_id"] = 0;
  187. std::string dev_name = "device_" + std::to_string(dev_addr);
  188. if (dev_type == 1) { // 温湿度
  189. device_name = "温湿度-" + postfix + std::to_string(dev_addr);
  190. json_save["device_name"] = "温湿度-" + postfix + std::to_string(dev_addr);
  191. json_save["device_id"] = dev_addr;
  192. // 温度对象
  193. nlohmann::json temp_data;
  194. temp_data["name"] = "温度";
  195. temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
  196. temp_data["format"] = "℃";
  197. temp_data["format_id"] = 40;
  198. json_save["data"].push_back(temp_data);
  199. // 湿度对象
  200. nlohmann::json humidity_data;
  201. humidity_data["name"] = "湿度";
  202. humidity_data["value"] = ((buffer[9] << 8) + buffer[10]);
  203. humidity_data["format"] = "%RH";
  204. humidity_data["format_id"] = 40;
  205. json_save["data"].push_back(humidity_data);
  206. } else if (dev_type == 2) { // 水浸
  207. device_name = "水浸-" + postfix + std::to_string(dev_addr);
  208. json_save["device_name"] = "水浸-" + postfix + std::to_string(dev_addr);
  209. json_save["device_id"] = dev_addr;
  210. // 水浸对象
  211. nlohmann::json water_data;
  212. water_data["name"] = "水浸状态";
  213. water_data["value"] = ((buffer[7] << 8) + buffer[8]); // 0 表示无水浸,1 表示有水浸
  214. // if((buffer[7] << 8) + buffer[8] == 0)
  215. // water_data["value"] = "正常";
  216. // else
  217. // water_data["value"] = "告警";
  218. water_data["format"] = "";
  219. water_data["format_id"] = 0;
  220. json_save["data"].push_back(water_data);
  221. } else if (dev_type == 3) { // 烟感
  222. device_name = "烟感-" + postfix + std::to_string(dev_addr);
  223. json_save["device_name"] = "烟感-" + postfix + std::to_string(dev_addr);
  224. json_save["device_id"] = dev_addr;
  225. // 烟感对象
  226. nlohmann::json smoke_data;
  227. smoke_data["name"] = "报警状态";
  228. smoke_data["value"] = (buffer[7] << 8) + buffer[8];
  229. // if((buffer[7] << 8) + buffer[8] == 0)
  230. // smoke_data["value"] = "正常";
  231. // else
  232. // smoke_data["value"] = "告警";
  233. smoke_data["format"] = "";
  234. smoke_data["format_id"] = 0;
  235. json_save["data"].push_back(smoke_data);
  236. }else if (dev_type == 7) {
  237. device_name = "空调-" + postfix + std::to_string(dev_addr);
  238. json_save["device_name"] = "空调-" + postfix + std::to_string(dev_addr);
  239. json_save["device_id"] = dev_addr;
  240. // 开关对象
  241. nlohmann::json switch_data;
  242. switch_data["name"] = "开关";
  243. switch_data["value"] = ((buffer[7] << 8) + buffer[8]);
  244. switch_data["format"] = "";
  245. switch_data["format_id"] = 0;
  246. json_save["data"].push_back(switch_data);
  247. // 模式对象
  248. nlohmann::json mode_data;
  249. mode_data["name"] = "模式";
  250. mode_data["value"] = ((buffer[9] << 8) + buffer[10]);
  251. mode_data["format"] = "";
  252. mode_data["format_id"] = 0;
  253. json_save["data"].push_back(mode_data);
  254. // 模式对象
  255. nlohmann::json set_temperature_data;
  256. set_temperature_data["name"] = "设定温度";
  257. set_temperature_data["value"] = ((buffer[11] << 8) + buffer[12]);
  258. set_temperature_data["format"] = "℃";
  259. set_temperature_data["format_id"] = 40;
  260. json_save["data"].push_back(set_temperature_data);
  261. // 模式对象
  262. nlohmann::json wind_speed_data;
  263. wind_speed_data["name"] = "风速";
  264. wind_speed_data["value"] = ((buffer[13] << 8) + buffer[14]);
  265. wind_speed_data["format"] = "";
  266. wind_speed_data["format_id"] = 40;
  267. json_save["data"].push_back(wind_speed_data);
  268. // 模式对象
  269. nlohmann::json wind_direction_data;
  270. wind_direction_data["name"] = "风向";
  271. wind_direction_data["value"] = ((buffer[15] << 8) + buffer[16]);
  272. wind_direction_data["format"] = "";
  273. wind_direction_data["format_id"] = 0;
  274. json_save["data"].push_back(wind_direction_data);
  275. // 上报周期
  276. nlohmann::json report_period;
  277. report_period["name"] = "上报周期";
  278. report_period["value"] = ((buffer[17] << 8) + buffer[18]);
  279. report_period["format"] = "s";
  280. report_period["format_id"] = 0;
  281. json_save["data"].push_back(report_period);
  282. }else if (dev_type == 6) { // 照明
  283. device_name = "照明-" + postfix + std::to_string(dev_addr);
  284. json_save["device_name"] = "照明-" + postfix + std::to_string(dev_addr);
  285. json_save["device_id"] = dev_addr;
  286. //开关
  287. nlohmann::json switch_data;
  288. switch_data["name"] = "开关";
  289. switch_data["value"] = (buffer[7] << 8) + buffer[8];
  290. switch_data["format"] = "";
  291. switch_data["format_id"] = 0;
  292. json_save["data"].push_back(switch_data);
  293. // 上报周期
  294. nlohmann::json report_period;
  295. report_period["name"] = "上报周期";
  296. report_period["value"] = ((buffer[9] << 8) + buffer[10]);
  297. report_period["format"] = "s";
  298. report_period["format_id"] = 0;
  299. json_save["data"].push_back(report_period);
  300. }else if (dev_type == 8) { // 门磁
  301. device_name = "门磁-" + postfix + std::to_string(dev_addr);
  302. json_save["device_name"] = "门磁-" + postfix + std::to_string(dev_addr);
  303. json_save["device_id"] = dev_addr;
  304. //开关
  305. nlohmann::json switch_data;
  306. switch_data["name"] = "开关";
  307. switch_data["value"] = (buffer[7] << 8) + buffer[8];
  308. switch_data["format"] = "";
  309. switch_data["format_id"] = 0;
  310. json_save["data"].push_back(switch_data);
  311. // 上报周期
  312. nlohmann::json report_period;
  313. report_period["name"] = "上报周期";
  314. report_period["value"] = ((buffer[9] << 8) + buffer[10]);
  315. report_period["format"] = "s";
  316. report_period["format_id"] = 0;
  317. json_save["data"].push_back(report_period);
  318. }else if (dev_type == 5) { // 风机
  319. device_name = "风机-" + postfix + std::to_string(dev_addr);
  320. json_save["device_name"] = "风机-" + postfix + std::to_string(dev_addr);
  321. json_save["device_id"] = dev_addr;
  322. //开关
  323. nlohmann::json switch_data;
  324. switch_data["name"] = "开关";
  325. switch_data["value"] = (buffer[7] << 8) + buffer[8];
  326. switch_data["format"] = "";
  327. switch_data["format_id"] = 0;
  328. json_save["data"].push_back(switch_data);
  329. // 上报周期
  330. nlohmann::json report_period;
  331. report_period["name"] = "上报周期";
  332. report_period["value"] = ((buffer[9] << 8) + buffer[10]);
  333. report_period["format"] = "s";
  334. report_period["format_id"] = 0;
  335. json_save["data"].push_back(report_period);
  336. }else if (dev_type == 9) { // 智能门锁
  337. device_name = "智能门锁-" + postfix + std::to_string(dev_addr);
  338. json_save["device_name"] = "智能门锁-" + postfix + std::to_string(dev_addr);
  339. json_save["device_id"] = dev_addr;
  340. //开关
  341. nlohmann::json switch_data;
  342. switch_data["name"] = "门状态";
  343. switch_data["value"] = (buffer[7] << 8) + buffer[8];
  344. switch_data["format"] = "";
  345. switch_data["format_id"] = 0;
  346. json_save["data"].push_back(switch_data);
  347. switch_data["name"] = "门控制";
  348. switch_data["value"] = (buffer[9] << 8) + buffer[10];
  349. switch_data["format"] = "";
  350. switch_data["format_id"] = 0;
  351. json_save["data"].push_back(switch_data);
  352. switch_data["name"] = "上报周期";
  353. switch_data["value"] = (buffer[11] << 8) + buffer[12];
  354. switch_data["format"] = "s";
  355. switch_data["format_id"] = 0;
  356. json_save["data"].push_back(switch_data);
  357. }else if (dev_type == 4) { // 双气
  358. device_name = "双气-" + postfix + std::to_string(dev_addr);
  359. json_save["device_name"] = "双气-" + postfix + std::to_string(dev_addr);
  360. json_save["device_id"] = dev_addr;
  361. // 氧气浓度
  362. nlohmann::json temp_data;
  363. temp_data["name"] = "氧气浓度";
  364. temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
  365. temp_data["format"] = "%";
  366. temp_data["format_id"] = 0;
  367. json_save["data"].push_back(temp_data);
  368. // SF6浓度
  369. nlohmann::json humidity_data;
  370. humidity_data["name"] = "SF6浓度";
  371. humidity_data["value"] = ((buffer[9] << 8) + buffer[10])/10.0;
  372. humidity_data["format"] = "ppm";
  373. humidity_data["format_id"] = 0;
  374. json_save["data"].push_back(humidity_data);
  375. // 上报周期
  376. nlohmann::json report_period;
  377. report_period["name"] = "上报周期";
  378. report_period["value"] = ((buffer[11] << 8) + buffer[12]);
  379. report_period["format"] = "s";
  380. report_period["format_id"] = 0;
  381. json_save["data"].push_back(report_period);
  382. }else if (dev_type == 10) { // 噪声
  383. device_name = "噪声-" + postfix + std::to_string(dev_addr);
  384. json_save["device_name"] = "噪声-" + postfix + std::to_string(dev_addr);
  385. json_save["device_id"] = dev_addr;
  386. // 噪声值
  387. nlohmann::json temp_data;
  388. temp_data["name"] = "噪声值";
  389. temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
  390. temp_data["format"] = "db";
  391. temp_data["format_id"] = 40;
  392. json_save["data"].push_back(temp_data);
  393. // 上报周期
  394. nlohmann::json report_period;
  395. report_period["name"] = "上报周期";
  396. report_period["value"] = ((buffer[9] << 8) + buffer[10]);
  397. report_period["format"] = "s";
  398. report_period["format_id"] = 0;
  399. json_save["data"].push_back(report_period);
  400. }else if (dev_type == 11) { // 噪声
  401. device_name = "臭氧-" + postfix + std::to_string(dev_addr);
  402. json_save["device_name"] = "臭氧-" + postfix + std::to_string(dev_addr);
  403. json_save["device_id"] = dev_addr;
  404. // 臭氧浓度
  405. nlohmann::json temp_data;
  406. temp_data["name"] = "臭氧浓度";
  407. temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
  408. temp_data["format"] = "0.1ppm";
  409. temp_data["format_id"] = 40;
  410. json_save["data"].push_back(temp_data);
  411. // 上报周期
  412. nlohmann::json report_period;
  413. report_period["name"] = "上报周期";
  414. report_period["value"] = ((buffer[11] << 8) + buffer[12]);
  415. report_period["format"] = "s";
  416. report_period["format_id"] = 0;
  417. json_save["data"].push_back(report_period);
  418. }
  419. else if (dev_type == 12) { // 蓄电池
  420. device_name = "蓄电池-" + std::to_string(dev_addr);
  421. json_save["device_name"] = "蓄电池-" + std::to_string(dev_addr);
  422. json_save["device_id"] = dev_addr;
  423. // 开关对象
  424. nlohmann::json group_voltage;
  425. group_voltage["name"] = "组电压";
  426. group_voltage["value"] = (((buffer[7] << 8) + buffer[8]))/10.0;
  427. group_voltage["format"] = "V";
  428. group_voltage["format_id"] = 0;
  429. json_save["data"].push_back(group_voltage);
  430. // 模式对象
  431. nlohmann::json group_current;
  432. group_current["name"] = "组电流";
  433. group_current["value"] = ((buffer[9] << 8) + buffer[10]) / 100.0;
  434. group_current["format"] = "A";
  435. group_current["format_id"] = 0;
  436. json_save["data"].push_back(group_current);
  437. for(int i = 0; i <= 8; i++) {
  438. nlohmann::json sigle_voltage;
  439. sigle_voltage["name"] = "电池-" + std::to_string(i+1) + " 电压";
  440. sigle_voltage["value"] = ((buffer[11 + i * 2] << 8) + buffer[12 + i * 2]) / 1000.0;
  441. sigle_voltage["format"] = "V";
  442. sigle_voltage["format_id"] = 40;
  443. json_save["data"].push_back(sigle_voltage);
  444. }
  445. // 模式对象
  446. for(int i = 0; i <= 8; i++) {
  447. nlohmann::json sigle_temp;
  448. sigle_temp["name"] = "电池-" + std::to_string(i+1) + " 温度";
  449. sigle_temp["value"] = ((buffer[29 + i * 2] << 8) + buffer[30 + i * 2]) / 100.0;
  450. sigle_temp["format"] = "℃";
  451. sigle_temp["format_id"] = 40;
  452. json_save["data"].push_back(sigle_temp);
  453. }
  454. // 模式对象
  455. for(int i = 0; i <= 8; i++) {
  456. nlohmann::json sigle_resistance;
  457. sigle_resistance["name"] = "电池-" + std::to_string(i+1) + " 内阻";
  458. sigle_resistance["value"] = ((buffer[47 + i * 2] << 8) + buffer[48 + i * 2]) / 1000.0;
  459. sigle_resistance["format"] = "mΩ";
  460. sigle_resistance["format_id"] = 0;
  461. json_save["data"].push_back(sigle_resistance);
  462. }
  463. for(int i = 0; i <= 8; i++) {
  464. nlohmann::json sigle_volumn;
  465. sigle_volumn["name"] = "电池-" + std::to_string(i+1) + " 容量";
  466. sigle_volumn["value"] = ((buffer[65 + i * 2] << 8) + buffer[66 + i * 2]) / 100.0;
  467. sigle_volumn["format"] = "";
  468. sigle_volumn["format_id"] = 0;
  469. json_save["data"].push_back(sigle_volumn);
  470. }
  471. // 上报周期
  472. nlohmann::json report_period;
  473. report_period["name"] = "上报周期";
  474. report_period["value"] = ((buffer[83] << 8) + buffer[84]);
  475. report_period["format"] = "s";
  476. report_period["format_id"] = 0;
  477. json_save["data"].push_back(report_period);
  478. }else{
  479. std::cout << "未知设备类型: " << dev_type << std::endl;
  480. }
  481. // std::cout << "devaice_name: " << dev_name << std::endl;
  482. // std::cout << "json_save: "<< json_save.dump(1) << std::endl;
  483. return json_save;
  484. }
  485. // 处理客户端连接
  486. void TcpServer::handle_client(int client_socket, const std::string& ip) {
  487. uint8_t buffer[BUFFER_SIZE];
  488. while (true) {
  489. // 检测连接状态
  490. fd_set read_fds;
  491. FD_ZERO(&read_fds);
  492. FD_SET(client_socket, &read_fds);
  493. struct timeval timeout = {1, 0}; // 1秒超时
  494. int activity = select(client_socket + 1, &read_fds, nullptr, nullptr, &timeout);
  495. if (activity < 0 && errno != EINTR) {
  496. close(client_socket);
  497. this->conn_num--;
  498. std::cout << "连接已断开: " << this->conn_num << std::endl;
  499. LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
  500. break; // 出错退出
  501. }
  502. if (FD_ISSET(client_socket, &read_fds)) {
  503. memset(buffer, 0, BUFFER_SIZE);
  504. int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
  505. if (bytes_received <= 0) {
  506. close(client_socket);
  507. this->conn_num--;
  508. std::cout << "连接已断开,当前连接数量是: " << this->conn_num << std::endl;
  509. LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
  510. break;
  511. }
  512. std::cout << "接收到对端消息, size = " << bytes_received << " data = ";
  513. for (int i = 0; i < bytes_received; i++) {
  514. printf("0x%02x ", buffer[i]);
  515. }
  516. printf("\n");
  517. if (bytes_received < 11) {
  518. std::cout << "消息太短,丢弃!" << std::endl;
  519. continue;
  520. }
  521. // if(calculate_crc16(buffer, bytes_received - 2)){
  522. uint16_t CRC = calculate_crc16(buffer, bytes_received - 2);
  523. if (((buffer[bytes_received - 1] << 8) != (CRC & (0xff << 8))) || (buffer[bytes_received - 2] != (CRC & 0xff))) {
  524. std::cout << "crc错误,丢弃!" << std::endl;
  525. continue;
  526. }
  527. // std::cout << "CRC = " << CRC <<std::endl;
  528. std::string deviceName;
  529. int dev_addr = buffer[0];
  530. nlohmann::json json_save = decode_modbus_msg(buffer, deviceName);
  531. // 添加额外信息
  532. json_save["dev_addr"] = dev_addr;
  533. json_save["device_name"] = deviceName;
  534. // 放入队列
  535. db_queue.push(json_save);
  536. sqlite3_stmt* stmt = nullptr;
  537. sqlite3* db = nullptr;
  538. const std::string dbPath = "/usr/local/bin/database/sqlite/device_position.db";
  539. // 直接打开数据库(不会自动创建目录或建表)
  540. if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
  541. std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
  542. continue;
  543. }
  544. // 检查设备是否已存在
  545. std::string checkSQL = "SELECT COUNT(*) FROM device_position WHERE name = ?;";
  546. if (sqlite3_prepare_v2(db, checkSQL.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
  547. std::cerr << "Prepare failed: " << sqlite3_errmsg(db) << std::endl;
  548. sqlite3_close(db);
  549. continue;
  550. }
  551. sqlite3_bind_text(stmt, 1, deviceName.c_str(), -1, SQLITE_STATIC);
  552. bool exists = false;
  553. if (sqlite3_step(stmt) == SQLITE_ROW) {
  554. exists = (sqlite3_column_int(stmt, 0) > 0);
  555. }
  556. sqlite3_finalize(stmt);
  557. if (exists) {
  558. std::cout << "设备 [" << deviceName << "] 已存在,跳过插入。 ip=" << ip << std::endl;
  559. if(ip == "172.16.111.60" || ip == "172.16.111.61" || ip == "172.16.111.62"
  560. || ip == "172.16.111.64" || ip == "172.16.111.63" || ip == "172.16.111.65" || ip == "172.16.111.68" || ip == "172.16.111.70") {
  561. sqlite3_close(db);
  562. close(client_socket);
  563. this->conn_num--;
  564. std::cout << "连接已经断开: " << ip << "当前连接数量:" << this->conn_num << std::endl;
  565. LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
  566. break;
  567. }
  568. sqlite3_close(db);
  569. continue;
  570. }
  571. // 插入新设备
  572. std::string insertSQL = "INSERT INTO device_position (name, x, y) VALUES (?, 0.5, 0.25);";
  573. if (sqlite3_prepare_v2(db, insertSQL.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
  574. std::cerr << "Insert prepare failed: " << sqlite3_errmsg(db) << std::endl;
  575. sqlite3_close(db);
  576. continue;
  577. }
  578. sqlite3_bind_text(stmt, 1, deviceName.c_str(), -1, SQLITE_STATIC);
  579. if (sqlite3_step(stmt) != SQLITE_DONE) {
  580. std::cerr << "插入失败: " << sqlite3_errmsg(db) << std::endl;
  581. sqlite3_finalize(stmt);
  582. sqlite3_close(db);
  583. continue;
  584. }
  585. sqlite3_finalize(stmt);
  586. sqlite3_close(db);
  587. std::cout << "设备 [" << deviceName << "] 插入成功。" << std::endl;
  588. if(ip == "172.16.111.60" || ip == "172.16.111.61" || ip == "172.16.111.62" || ip == "172.16.111.64"
  589. || ip == "172.16.111.64" || ip == "172.16.111.63" || ip == "172.16.111.65" || ip == "172.16.111.68" || ip == "172.16.111.70") {
  590. close(client_socket);
  591. this->conn_num--;
  592. std::cout << "连接已经断开: " << ip << "当前连接数量:" << this->conn_num << std::endl;
  593. LOG_Debug("%s 连接已经断开 当前连接数量:%d", ip.c_str(), this->conn_num);
  594. break;
  595. }
  596. }
  597. }
  598. }