智能家居服务器:基于Linux C实现的TCP通信和SQLite数据库交互
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sqlite3.h>
#define PORT 12345 #define MAX_CLIENTS 10 #define DATABASE_FILE "database.db"
typedef struct { int uid; char device_name[10]; char device_state[10]; char value[10]; char mode[10]; } Status;
int process_request(int client_socket, int userid); int get_status(int userid, Status *status); void analyze_status(Status *status, char *suggestion); int send_response(int client_socket, const char *response);
int main() { int server_socket, client_socket, addr_len; struct sockaddr_in server_addr, client_addr;
// 创建服务器套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror("Error creating socket");
exit(1);
}
// 设置服务器地址和端口
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
// 绑定服务器套接字到指定地址和端口
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Error binding socket");
exit(1);
}
// 监听连接请求
if (listen(server_socket, MAX_CLIENTS) < 0) {
perror("Error listening for connections");
exit(1);
}
printf("Server started. Listening on port %d...
", PORT);
while (1) {
addr_len = sizeof(client_addr);
// 接受客户端连接请求
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, (socklen_t *)&addr_len);
if (client_socket < 0) {
perror("Error accepting connection");
exit(1);
}
printf("New client connected: %s
", inet_ntoa(client_addr.sin_addr));
// 处理客户端请求
if (fork() == 0) {
close(server_socket);
process_request(client_socket, 0);
close(client_socket);
exit(0);
}
close(client_socket);
}
close(server_socket);
return 0;
}
int process_request(int client_socket, int userid) { int status; char buffer[1024]; Status status_data; char suggestion[1024];
// 读取userid
status = read(client_socket, &userid, sizeof(userid));
if (status < 0) {
perror("Error reading userid");
return -1;
}
// 从数据库获取最新的状态信息
status = get_status(userid, &status_data);
if (status < 0) {
perror("Error getting status from database");
return -1;
}
// 分析状态信息并生成建议
analyze_status(&status_data, suggestion);
// 发送建议给客户端
status = send_response(client_socket, suggestion);
if (status < 0) {
perror("Error sending response");
return -1;
}
return 0;
}
int get_status(int userid, Status *status) { sqlite3 *db; sqlite3_stmt *stmt; char query[1024]; int status_code;
// 打开数据库
status_code = sqlite3_open(DATABASE_FILE, &db);
if (status_code != SQLITE_OK) {
fprintf(stderr, "Error opening database: %s\n", sqlite3_errmsg(db));
return -1;
}
// 构建查询语句
snprintf(query, sizeof(query), "SELECT * FROM Status WHERE uid = %d ORDER BY sid DESC LIMIT 1", userid);
// 执行查询
status_code = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
if (status_code != SQLITE_OK) {
fprintf(stderr, "Error preparing statement: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
}
// 获取查询结果
status_code = sqlite3_step(stmt);
if (status_code == SQLITE_ROW) {
status->uid = sqlite3_column_int(stmt, 1);
strncpy(status->device_name, (const char *)sqlite3_column_text(stmt, 2), sizeof(status->device_name));
strncpy(status->device_state, (const char *)sqlite3_column_text(stmt, 3), sizeof(status->device_state));
strncpy(status->value, (const char *)sqlite3_column_text(stmt, 4), sizeof(status->value));
strncpy(status->mode, (const char *)sqlite3_column_text(stmt, 5), sizeof(status->mode));
} else if (status_code == SQLITE_DONE) {
fprintf(stderr, "No data found for userid %d\n", userid);
} else {
fprintf(stderr, "Error retrieving data: %s\n", sqlite3_errmsg(db));
sqlite3_finalize(stmt);
sqlite3_close(db);
return -1;
}
// 释放资源
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
void analyze_status(Status *status, char *suggestion) { // 根据状态信息生成建议 if (strcmp(status->device_name, "空调") == 0) { int temperature = atoi(status->value); if (temperature < 24) { snprintf(suggestion, 1024, "空调温度过低,建议提高温度至26℃"); } else { snprintf(suggestion, 1024, "空调温度正常"); } } else if (strcmp(status->device_name, "加湿器") == 0) { int humidity = atoi(status->value); if (humidity < 40 || humidity > 70) { snprintf(suggestion, 1024, "加湿器湿度不适宜,建议调整加湿器湿度"); } else { snprintf(suggestion, 1024, "加湿器湿度正常"); } } else { snprintf(suggestion, 1024, "未知设备"); } }
int send_response(int client_socket, const char *response) { int status;
// 发送建议给客户端
status = write(client_socket, response, strlen(response));
if (status < 0) {
perror("Error sending response");
return -1;
}
return 0;
}
原文地址: http://www.cveoy.top/t/topic/fCb8 著作权归作者所有。请勿转载和采集!