智能家居状态服务器-数据库交互与建议生成
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
#define DATABASE 'database.db' #define PORT 8080
typedef struct { int uid; char device_name[10]; char device_state[10]; char value[10]; char mode[10]; } Status;
int get_status_by_uid(int uid, Status *status) { sqlite3 *db; sqlite3_stmt *stmt; int rc;
rc = sqlite3_open(DATABASE, &db);
if (rc != SQLITE_OK) {
fprintf(stderr, 'Cannot open database: %s\n', sqlite3_errmsg(db));
return rc;
}
char query[100];
sprintf(query, 'SELECT * FROM Status WHERE uid = %d ORDER BY sid DESC LIMIT 1', uid);
rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, 'Failed to prepare statement: %s\n', sqlite3_errmsg(db));
return rc;
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
fprintf(stderr, 'Failed to execute statement: %s\n', sqlite3_errmsg(db));
return rc;
}
if (rc == SQLITE_DONE) {
status->uid = -1;
} else {
status->uid = sqlite3_column_int(stmt, 1);
strcpy(status->device_name, sqlite3_column_text(stmt, 2));
strcpy(status->device_state, sqlite3_column_text(stmt, 3));
strcpy(status->value, sqlite3_column_text(stmt, 4));
strcpy(status->mode, sqlite3_column_text(stmt, 5));
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return SQLITE_OK;
}
void process_request(int client_socket) { char buffer[1024]; memset(buffer, 0, sizeof(buffer));
ssize_t bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_received < 0) {
perror('Error receiving data from client');
return;
}
printf('Received request from client: %s\n', buffer);
int uid;
sscanf(buffer, '{"userid": %d}', &uid);
Status status;
int rc = get_status_by_uid(uid, &status);
if (rc != SQLITE_OK) {
perror('Error getting status from database');
return;
}
char response[1024];
memset(response, 0, sizeof(response));
if (status.uid == -1) {
strcpy(response, 'No status found for the given userid');
} else {
if (strcmp(status.device_name, '空调') == 0 && atoi(status.value) < 24) {
strcpy(response, '空调温度过低,建议提高温度至26℃');
} else if (strcmp(status.device_name, '加湿器') == 0 && (atoi(status.value) < 40 || atoi(status.value) > 70)) {
strcpy(response, '加湿器湿度过高或过低,建议调整加湿器湿度');
} else {
strcpy(response, 'No suggestion');
}
}
ssize_t bytes_sent = send(client_socket, response, strlen(response), 0);
if (bytes_sent < 0) {
perror('Error sending response to client');
return;
}
printf('Sent response to client: %s\n', response);
}
int main() { int server_socket, client_socket; struct sockaddr_in server_address, client_address; socklen_t client_address_length = sizeof(client_address);
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0) {
perror('Error creating server socket');
exit(EXIT_FAILURE);
}
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(PORT);
if (bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
perror('Error binding server socket');
exit(EXIT_FAILURE);
}
if (listen(server_socket, 5) < 0) {
perror('Error listening for connections');
exit(EXIT_FAILURE);
}
printf('Server is listening on port %d\n', PORT);
while (1) {
client_socket = accept(server_socket, (struct sockaddr *) &client_address, &client_address_length);
if (client_socket < 0) {
perror('Error accepting client connection');
exit(EXIT_FAILURE);
}
printf('Accepted client connection from %s:%d\n', inet_ntoa(client_address.sin_addr), ntohs(client_address.sin_port));
pid_t pid = fork();
if (pid == 0) {
close(server_socket);
process_request(client_socket);
close(client_socket);
exit(EXIT_SUCCESS);
} else if (pid < 0) {
perror('Error forking child process');
exit(EXIT_FAILURE);
} else {
close(client_socket);
}
}
close(server_socket);
return 0;
}
原文地址: https://www.cveoy.top/t/topic/fBET 著作权归作者所有。请勿转载和采集!