TcpServer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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. // 回调函数,用于处理查询结果
  10. static int sql_callback(void *NotUsed, int argc, char **argv, char **azColName) {
  11. for (int i = 0; i < argc; i++) {
  12. printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  13. }
  14. printf("\n");
  15. return 0;
  16. }
  17. // 计算CRC16的表格(预先计算以提高效率)
  18. uint16_t crc16_table[256];
  19. // 初始化CRC16表格
  20. void init_crc16_table() {
  21. uint16_t polynomial = 0xA001;
  22. for (uint16_t i = 0; i < 256; i++) {
  23. uint16_t crc = i;
  24. for (uint8_t j = 0; j < 8; j++) {
  25. if (crc & 0x0001) {
  26. crc = (crc >> 1) ^ polynomial;
  27. } else {
  28. crc >>= 1;
  29. }
  30. }
  31. crc16_table[i] = crc;
  32. }
  33. }
  34. // 计算给定数据缓冲区的CRC16校验值
  35. uint16_t calculate_crc16(uint8_t *data, size_t length) {
  36. uint16_t crc = 0xFFFF; // 初始值
  37. for (size_t i = 0; i < length; i++) {
  38. uint8_t table_index = (crc ^ data[i]) & 0xFF;
  39. crc = (crc >> 8) ^ crc16_table[table_index];
  40. }
  41. return crc;
  42. }
  43. // 构造函数
  44. TcpServer::TcpServer(int port) : conn_num(0), running(true) {
  45. server_fd = socket(AF_INET, SOCK_STREAM, 0);
  46. if (server_fd < 0) {
  47. perror("Socket creation failed");
  48. throw std::runtime_error("Socket creation failed");
  49. }
  50. address.sin_family = AF_INET;
  51. address.sin_addr.s_addr = INADDR_ANY;
  52. address.sin_port = htons(port);
  53. addrlen = sizeof(address);
  54. int opt = 1;
  55. // Set socket options
  56. if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
  57. perror("Setsockopt failed");
  58. std::cout << "port = " << port << std::endl;
  59. close(server_fd);
  60. throw std::runtime_error("Setsockopt failed");
  61. }
  62. // Bind socket to address
  63. if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
  64. perror("Bind failed");
  65. close(server_fd);
  66. throw std::runtime_error("Bind failed");
  67. }
  68. // Listen for incoming connections
  69. if (listen(server_fd, 3) < 0) {
  70. perror("Listen failed");
  71. close(server_fd);
  72. throw std::runtime_error("Listen failed");
  73. }
  74. std::cout << "Server listening on port " << port << std::endl;
  75. }
  76. // 析构函数
  77. TcpServer::~TcpServer() {
  78. running = false;
  79. if (accept_thread.joinable()) {
  80. accept_thread.join();
  81. }
  82. for (auto &th : threads) {
  83. if (th.joinable()) {
  84. th.join();
  85. }
  86. }
  87. close(server_fd);
  88. }
  89. // 启动服务器
  90. void TcpServer::start_server() {
  91. std::cout << "Starting server..." << std::endl;
  92. // 初始化CRC16表格
  93. init_crc16_table();
  94. accept_thread = std::thread([this]() {
  95. while (this->running) {
  96. int new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
  97. if (new_socket < 0) {
  98. // 打印错误信息
  99. std::cerr << "Accept failed with error: " << strerror(errno) << std::endl;
  100. if (errno == EINTR) {
  101. // 如果是信号中断,继续等待连接
  102. continue;
  103. } else {
  104. // 其他错误,继续等待连接
  105. continue;
  106. }
  107. }
  108. std::cout << "New client connected" << std::endl;
  109. {
  110. std::lock_guard<std::mutex> lock(mtx);
  111. this->conn_num++;
  112. std::cout << "Current connection count: " << this->conn_num << std::endl;
  113. }
  114. // Create a new thread to handle the client
  115. threads.emplace_back(&TcpServer::handle_client, this, new_socket);
  116. }
  117. });
  118. // accept_thread.detach(); // 让接受线程独立运行
  119. accept_thread.join();
  120. }
  121. // 处理客户端连接
  122. void TcpServer::handle_client(int client_socket) {
  123. uint8_t buffer[BUFFER_SIZE];
  124. while (true) {
  125. memset(buffer, 0, BUFFER_SIZE);
  126. int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
  127. if (bytes_received <= 0) {
  128. // Client disconnected or error
  129. std::cout << "Client disconnected or error occurred. bytes_received = " << bytes_received << std::endl;
  130. close(client_socket);
  131. this->conn_num --;
  132. std::cout << "Current connection count: " << this->conn_num << std::endl;
  133. break;
  134. }
  135. std::cout << "Received from client, size = " << bytes_received << " data = ";
  136. for(int i = 0;i < bytes_received; i++){
  137. printf("0x%02x ", buffer[i]);
  138. }
  139. printf("\n");
  140. if(bytes_received < 11){
  141. std::cout << "too short msg!" << std::endl;
  142. continue;
  143. }
  144. // if(calculate_crc16(buffer, bytes_received - 2)){
  145. uint16_t CRC = calculate_crc16(buffer, bytes_received - 2);
  146. if(((buffer[bytes_received - 1]<<8) != (CRC&(0xff<<8))) || (buffer[bytes_received - 2] != (CRC&0xff))){
  147. std::cout << "error crc msg!" << std::endl;
  148. continue;
  149. }
  150. std::cout << "CRC = " << calculate_crc16(buffer, bytes_received - 2) <<std::endl;
  151. int dev_addr = buffer[0];
  152. int fun_code = buffer[1];
  153. int data_len = buffer[2];
  154. int dev_type = buffer[6];
  155. std::string device_name;
  156. nlohmann::json json_save;
  157. // 公共字段
  158. json_save["status"] = "run";
  159. json_save["gateway_id"] = 0;
  160. std::string dev_name = "device_" + std::to_string(dev_addr);
  161. if (dev_type == 1) { // 温湿度
  162. device_name = "温湿度-" + std::to_string(dev_addr);
  163. json_save["device_name"] = "温湿度-" + std::to_string(dev_addr);
  164. json_save["device_id"] = dev_addr;
  165. // 温度对象
  166. nlohmann::json temp_data;
  167. temp_data["name"] = "温度";
  168. temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
  169. temp_data["format"] = "℃";
  170. temp_data["format_id"] = 40;
  171. json_save["data"].push_back(temp_data);
  172. // 湿度对象
  173. nlohmann::json humidity_data;
  174. humidity_data["name"] = "湿度";
  175. humidity_data["value"] = ((buffer[9] << 8) + buffer[10]);
  176. humidity_data["format"] = "%RH";
  177. humidity_data["format_id"] = 40;
  178. json_save["data"].push_back(humidity_data);
  179. } else if (dev_type == 2) { // 水浸
  180. device_name = "水浸-" + std::to_string(dev_addr);
  181. json_save["device_name"] = "水浸-" + std::to_string(dev_addr);
  182. json_save["device_id"] = dev_addr;
  183. // 水浸对象
  184. nlohmann::json water_data;
  185. water_data["name"] = "水浸状态";
  186. water_data["value"] = ((buffer[7] << 8) + buffer[8]); // 0 表示无水浸,1 表示有水浸
  187. water_data["format"] = "";
  188. water_data["format_id"] = 0;
  189. json_save["data"].push_back(water_data);
  190. } else if (dev_type == 3) { // 烟感
  191. device_name = "烟感-" + std::to_string(dev_addr);
  192. json_save["device_name"] = "烟感-" + std::to_string(dev_addr);
  193. json_save["device_id"] = dev_addr;
  194. // 烟感对象
  195. nlohmann::json smoke_data;
  196. smoke_data["name"] = "报警状态";
  197. smoke_data["value"] = ((buffer[7] << 8) + buffer[8]); // 0 表示无烟,1 表示有烟
  198. smoke_data["format"] = "";
  199. smoke_data["format_id"] = 0;
  200. json_save["data"].push_back(smoke_data);
  201. }
  202. // else if (dev_type == 7) { // 烟感
  203. // device_name = "空调-" + std::to_string(dev_addr);
  204. // json_save["device_name"] = "空调-" + std::to_string(dev_addr);
  205. // json_save["device_id"] = dev_addr;
  206. //
  207. // // 开关对象
  208. // nlohmann::json switch_data;
  209. // switch_data["name"] = "开关";
  210. // switch_data["value"] = ((buffer[7] << 8) + buffer[8]);
  211. // switch_data["format"] = "";
  212. // switch_data["format_id"] = 0;
  213. // json_save["data"].push_back(switch_data);
  214. // // 模式对象
  215. // nlohmann::json mode_data;
  216. // mode_data["name"] = "模式";
  217. // mode_data["value"] = ((buffer[9] << 8) + buffer[10]);
  218. // mode_data["format"] = "";
  219. // mode_data["format_id"] = 0;
  220. // json_save["data"].push_back(mode_data);
  221. // // 模式对象
  222. // nlohmann::json set_temperature_data;
  223. // set_temperature_data["name"] = "设定温度";
  224. // set_temperature_data["value"] = ((buffer[11] << 8) + buffer[12]);
  225. // set_temperature_data["format"] = "℃";
  226. // set_temperature_data["format_id"] = 40;
  227. // json_save["data"].push_back(set_temperature_data);
  228. // // 模式对象
  229. // nlohmann::json wind_speed_data;
  230. // wind_speed_data["name"] = "风速";
  231. // wind_speed_data["value"] = ((buffer[13] << 8) + buffer[14]);
  232. // wind_speed_data["format"] = "m/s";
  233. // wind_speed_data["format_id"] = 40;
  234. // json_save["data"].push_back(wind_speed_data);
  235. // // 模式对象
  236. // nlohmann::json wind_direction_data;
  237. // wind_direction_data["name"] = "风向";
  238. // wind_direction_data["value"] = ((buffer[15] << 8) + buffer[16]);
  239. // wind_direction_data["format"] = "";
  240. // wind_direction_data["format_id"] = 0;
  241. // json_save["data"].push_back(wind_direction_data);
  242. // }
  243. // 创建 Redis 连接
  244. redisContext *context = redisConnect("127.0.0.1", 6379);
  245. if (context == NULL || context->err) {
  246. if (context) {
  247. printf("Error: %s\n", context->errstr);
  248. redisFree(context);
  249. } else {
  250. printf("Can't allocate redis context\n");
  251. }
  252. return ;
  253. }
  254. // 设置键值对
  255. std::cout << "devaice_name " << dev_name << "json_save "<< json_save.dump(4) << std::endl;
  256. std::string out = json_save.dump(0);
  257. redisReply *reply = (redisReply *)redisCommand(context, "SET %s %s", dev_name.c_str(), out.c_str());
  258. if (reply == NULL) {
  259. printf("Error: %s\n", context->errstr);
  260. redisFree(context);
  261. return ;
  262. }
  263. // 检查 SET 命令的返回值
  264. if (reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {
  265. // printf("Key '%s' set to value '%s'\n", key, value);
  266. } else {
  267. // printf("Failed to set key '%s'\n", key);
  268. }
  269. // 释放 reply 结构
  270. freeReplyObject(reply);
  271. // 断开 Redis 连接
  272. redisFree(context);
  273. sqlite3 *db;
  274. char *zErrMsg = 0;
  275. int rc;
  276. // 打开数据库连接
  277. rc = sqlite3_open("/usr/local/bin/database/sqlite/history_data.db", &db);
  278. if (rc) {
  279. fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  280. sqlite3_close(db);
  281. return;
  282. }
  283. // 创建表
  284. const char *sql_create_table =
  285. "CREATE TABLE IF NOT EXISTS history_data ("
  286. "id INTEGER PRIMARY KEY AUTOINCREMENT,"
  287. "data TEXT NOT NULL,"
  288. "time TEXT NOT NULL,"
  289. "device_id INTEGER NOT NULL,"
  290. "device_name TEXT NOT NULL,"
  291. "gateway_id INTEGER NOT NULL,"
  292. "status TEXT NOT NULL);";
  293. rc = sqlite3_exec(db, sql_create_table, sql_callback, 0, &zErrMsg);
  294. if (rc != SQLITE_OK) {
  295. fprintf(stderr, "SQL error: %s\n", zErrMsg);
  296. sqlite3_free(zErrMsg);
  297. } else {
  298. printf("Table created successfully\n");
  299. }
  300. // 插入数据
  301. const char *sql_insert_data =
  302. "INSERT INTO history_data (data, time, device_id, device_name, gateway_id, status) VALUES (?, ?, ?, ?, ?, ?);";
  303. // 准备插入语句
  304. sqlite3_stmt *stmt;
  305. rc = sqlite3_prepare_v2(db, sql_insert_data, -1, &stmt, 0);
  306. if (rc != SQLITE_OK) {
  307. fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
  308. sqlite3_close(db);
  309. return;
  310. }
  311. // 定义要插入的数据
  312. std::string sql_data = json_save["data"].dump();
  313. rc = sqlite3_bind_text(stmt, 1, sql_data.c_str(), -1, SQLITE_STATIC);
  314. // 获取当前时间
  315. time_t rawtime;
  316. struct tm *timeinfo;
  317. // 获取当前时间的时间戳
  318. time(&rawtime);
  319. // 将时间戳转换为本地时间
  320. timeinfo = localtime(&rawtime);
  321. // 提取年、月、日、时、分、秒
  322. int year = 1900 + timeinfo->tm_year; // tm_year 是从 1900 年开始的年数
  323. int month = 1 + timeinfo->tm_mon; // tm_mon 是从 0 开始的月份(0-11)
  324. int day = timeinfo->tm_mday; // tm_mday 是一个月中的第几天(1-31)
  325. int hour = timeinfo->tm_hour; // tm_hour 是小时(0-23)
  326. int minute = timeinfo->tm_min; // tm_min 是分钟(0-59)
  327. int second = timeinfo->tm_sec; // tm_sec 是秒(0-59)
  328. // 打印时间信息
  329. char time[30] = {};
  330. sprintf(time,"%d-%02d-%02d %02d:%02d:%02d",
  331. year, month, day, hour, minute, second);
  332. rc = sqlite3_bind_text(stmt, 2, time, -1, SQLITE_STATIC);
  333. rc = sqlite3_bind_int(stmt, 3, dev_addr);
  334. rc = sqlite3_bind_text(stmt, 4, device_name.c_str(), -1, SQLITE_STATIC);
  335. rc = sqlite3_bind_int(stmt, 5, 0);
  336. rc = sqlite3_bind_text(stmt, 6, "run", -1, SQLITE_STATIC);
  337. if (rc != SQLITE_OK) {
  338. fprintf(stderr, "Failed to bind parameters: %s\n", sqlite3_errmsg(db));
  339. sqlite3_finalize(stmt);
  340. sqlite3_close(db);
  341. return;
  342. }
  343. rc = sqlite3_step(stmt);
  344. if (rc != SQLITE_DONE) {
  345. fprintf(stderr, "Failed to execute insert: %s\n", sqlite3_errmsg(db));
  346. }
  347. // 清理语句
  348. sqlite3_finalize(stmt);
  349. // 查询数据
  350. // const char *sql_select_data = "SELECT * FROM history_data;";
  351. // rc = sqlite3_exec(db, sql_select_data, sql_callback, 0, &zErrMsg);
  352. // if (rc != SQLITE_OK) {
  353. // fprintf(stderr, "SQL error: %s\n", zErrMsg);
  354. // sqlite3_free(zErrMsg);
  355. // }
  356. // 关闭数据库连接
  357. sqlite3_close(db);
  358. }
  359. }