#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sqlite3.h>

#define MAX_BUFFER_SIZE 1024

// 数据库文件路径
#define DATABASE_PATH "home_automation.db"

// 服务器监听地址和端口
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8888

// 命令类型
enum CommandType {
    Login,
    Register,
    LightSwitch,
    LightIntensity,
    ACState,
    HumidifierState,
    CurtainState,
    CurtainHeight,
    Mode
};

// 命令结构体
typedef struct {
    enum CommandType type;
    char username[64];
    char password[64];
    bool state;
    int value;
} Command;

// 连接数据库
sqlite3 *connectDatabase() {
    sqlite3 *db;
    int rc;

    rc = sqlite3_open(DATABASE_PATH, &db);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        return NULL;
    }

    return db;
}

// 关闭数据库连接
void closeDatabase(sqlite3 *db) {
    sqlite3_close(db);
}

// 验证用户登录
bool verifyLogin(const char *username, const char *password) {
    sqlite3 *db = connectDatabase();
    bool result = false;

    if (db == NULL) {
        return result;
    }

    sqlite3_stmt *stmt;
    const char *query = "SELECT * FROM users WHERE username = ? AND password = ?";
    int rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
        closeDatabase(db);
        return result;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);

    if (rc == SQLITE_ROW) {
        result = true;
    }

    sqlite3_finalize(stmt);
    closeDatabase(db);
    return result;
}

// 注册新用户
bool registerUser(const char *username, const char *password) {
    sqlite3 *db = connectDatabase();
    bool result = false;

    if (db == NULL) {
        return result;
    }

    sqlite3_stmt *stmt;
    const char *query = "INSERT INTO users (username, password) VALUES (?, ?)";
    int rc = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
        closeDatabase(db);
        return result;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);

    rc = sqlite3_step(stmt);

    if (rc == SQLITE_DONE) {
        result = true;
    }

    sqlite3_finalize(stmt);
    closeDatabase(db);
    return result;
}

// 更新智能家居状态
bool updateHomeAutomationState(const char *username, const Command *command) {
    sqlite3 *db = connectDatabase();
    bool result = false;

    if (db == NULL) {
        return result;
    }

    sqlite3_stmt *stmt;
    int rc;

    switch (command->type) {
        case LightSwitch:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET light_state = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->state);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case LightIntensity:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET light_intensity = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->value);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case ACState:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET ac_state = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->state);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case HumidifierState:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET humidifier_state = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->state);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case CurtainState:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET curtain_state = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->state);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case CurtainHeight:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET curtain_height = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->value);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
        case Mode:
            rc = sqlite3_prepare_v2(db, "UPDATE home_status SET mode = ? WHERE username = ?", -1, &stmt, NULL);
            sqlite3_bind_int(stmt, 1, command->value);
            sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
            break;
    }

    if (rc != SQLITE_OK) {
        fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
        closeDatabase(db);
        return result;
    }

    rc = sqlite3_step(stmt);

    if (rc == SQLITE_DONE) {
        result = true;
    }

    sqlite3_finalize(stmt);
    closeDatabase(db);
    return result;
}

// 处理客户端请求
void handleClientRequest(int clientSocket) {
    char buffer[MAX_BUFFER_SIZE];
    memset(buffer, 0, MAX_BUFFER_SIZE);

    // 接收命令
    ssize_t bytesRead = recv(clientSocket, buffer, MAX_BUFFER_SIZE - 1, 0);

    if (bytesRead < 0) {
        perror("Failed to receive data");
        return;
    }

    Command command;
    memcpy(&command, buffer, sizeof(Command));

    // 处理命令
    bool success = false;

    switch (command.type) {
        case Login:
            success = verifyLogin(command.username, command.password);
            break;
        case Register:
            success = registerUser(command.username, command.password);
            break;
        case LightSwitch:
        case LightIntensity:
        case ACState:
        case HumidifierState:
        case CurtainState:
        case CurtainHeight:
        case Mode:
            success = updateHomeAutomationState(command.username, &command);
            break;
    }

    // 发送处理结果
    ssize_t bytesSent = send(clientSocket, &success, sizeof(bool), 0);

    if (bytesSent < 0) {
        perror("Failed to send data");
    }
}

int main() {
    int serverSocket;
    struct sockaddr_in serverAddress;

    // 创建服务器套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址和端口
    memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddress.sin_addr)) <= 0) {
        perror("Invalid address or address not supported");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字到地址和端口
    if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(serverSocket, 5) < 0) {
        perror("Failed to listen on socket");
        exit(EXIT_FAILURE);
    }

    printf("Server is running on %s:%d\n", SERVER_IP, SERVER_PORT);

    while (true) {
        int clientSocket;
        struct sockaddr_in clientAddress;
        socklen_t clientAddressLength;

        // 接受客户端连接
        clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);
        if (clientSocket < 0) {
            perror("Failed to accept client connection");
            continue;
        }

        // 处理客户端请求
        handleClientRequest(clientSocket);

        // 关闭客户端套接字
        close(clientSocket);
    }

    // 关闭服务器套接字
    close(serverSocket);

    return 0;
}

这段代码实现了一个基于Linux的C语言服务器,用于接收客户端的请求并处理。服务器通过TCP/IP协议监听指定地址和端口,接收到客户端的请求后,根据不同的命令类型进行相应的处理,包括用户登录验证、用户注册、更新智能家居状态等功能。服务器使用SQLite数据库来存储用户信息和智能家居状态,并提供了连接数据库和关闭数据库连接的函数。处理完客户端请求后,服务器将处理结果发送回客户端。

该服务器可以通过编译并运行,监听指定地址和端口,等待客户端连接。每当有客户端连接时,服务器会接收客户端的请求,并根据请求的命令类型进行相应的处理,然后将处理结果发送回客户端。你可以根据实际需求,修改和补充代码中的功能实现

基于Linux在Ubuntu上编写的C语言服务器代码示例:c#include stdioh#include stdlibh#include stringh#include stdboolh#include syssocketh#include netinetinh#include unistdh#include arpaineth#include sqlite3h#define MAX_BUFFE

原文地址: http://www.cveoy.top/t/topic/is82 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录