Linux C语言服务器与QT C++客户端的TCP通信及SQLite数据库应用

本文将介绍如何使用Linux C语言编写一个服务器,并使用QT C++编写客户端,实现以下功能:

  1. 客户端与服务器建立TCP连接。2. 客户端发送用户ID给服务器。3. 服务器根据用户ID查询SQLite数据库,获取设备状态信息。4. 服务器分析设备状态,生成建议信息。5. 服务器将建议信息发送给客户端。6. 客户端将建议信息显示在GUI界面上。

1. 服务器代码 (C语言)c#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 8888#define MAX_BUFFER_SIZE 1024

// 数据库回调函数static int callback(void *data, int argc, char **argv, char **azColName){ // 处理数据库查询结果 // 在这里进行设备状态分析并生成建议 // ... // 将建议发送给客户端 // ... return 0;}

int main() { int sockfd, newsockfd; struct sockaddr_in server_addr, client_addr; socklen_t sin_size; char buffer[MAX_BUFFER_SIZE];

// 创建服务器套接字    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {        perror('socket');        exit(1);    }

// 设置服务器地址和端口    server_addr.sin_family = AF_INET;    server_addr.sin_port = htons(PORT);    server_addr.sin_addr.s_addr = INADDR_ANY;    bzero(&(server_addr.sin_zero), 8);

// 绑定服务器套接字到指定地址和端口    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {        perror('bind');        exit(1);    }

// 监听连接请求    if (listen(sockfd, 5) == -1) {        perror('listen');        exit(1);    }

printf('Server is running...

');

while(1) {        sin_size = sizeof(struct sockaddr_in);

    // 接受客户端连接请求        if ((newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size)) == -1) {            perror('accept');            continue;        }

    printf('Client connected: %s

', inet_ntoa(client_addr.sin_addr));

    // 接收客户端发送的userid        memset(buffer, 0, MAX_BUFFER_SIZE);        if (recv(newsockfd, buffer, MAX_BUFFER_SIZE, 0) == -1) {            perror('recv');            close(newsockfd);            continue;        }

    int userid = atoi(buffer);

    // 连接数据库        sqlite3 *db;        if (sqlite3_open('database.db', &db) != SQLITE_OK) {            fprintf(stderr, 'Cannot open database: %s

', sqlite3_errmsg(db)); close(newsockfd); continue; }

    // 查询设备状态并生成建议        char sql[100];        sprintf(sql, 'SELECT device_name, value FROM Status WHERE uid = %d', userid);

    if (sqlite3_exec(db, sql, callback, NULL, NULL) != SQLITE_OK) {            fprintf(stderr, 'SQL error: %s

', sqlite3_errmsg(db)); close(newsockfd); continue; }

    // 关闭数据库连接        sqlite3_close(db);

    // 关闭与客户端的连接        close(newsockfd);    }

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

return 0;}

2. 客户端代码 (QT C++)

**2.1 头文件 (mainwindow.h)**cpp#ifndef MAINWINDOW_H#define MAINWINDOW_H

#include #include #include

QT_BEGIN_NAMESPACEnamespace Ui { class MainWindow; }QT_END_NAMESPACE

class MainWindow : public QMainWindow{ Q_OBJECT

public: MainWindow(QWidget *parent = nullptr); ~MainWindow();

private slots: void on_connectButton_clicked(); void onTcpConnected(); void onTcpDisconnected(); void onTcpReadyRead(); void onTcpError(QAbstractSocket::SocketError socketError);

private: Ui::MainWindow *ui; QTcpSocket *tcpSocket;};#endif // MAINWINDOW_H

**2.2 .cpp文件 (mainwindow.cpp)**cpp#include 'mainwindow.h'#include 'ui_mainwindow.h'

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){ ui->setupUi(this); tcpSocket = new QTcpSocket(this);

connect(tcpSocket, &QTcpSocket::connected, this, &MainWindow::onTcpConnected);    connect(tcpSocket, &QTcpSocket::disconnected, this, &MainWindow::onTcpDisconnected);    connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::onTcpReadyRead);    connect(tcpSocket, &QTcpSocket::errorOccurred, this, &MainWindow::onTcpError);}

MainWindow::~MainWindow(){ delete ui;}

void MainWindow::on_connectButton_clicked(){ QString ipAddress = '127.0.0.1'; // 替换为服务器IP地址 quint16 port = 8888;

tcpSocket->connectToHost(ipAddress, port);}

void MainWindow::onTcpConnected(){ // 连接成功,发送用户ID QString userId = '123'; // 替换为实际用户ID tcpSocket->write(userId.toUtf8());}

void MainWindow::onTcpDisconnected(){ ui->textEdit->append('连接已断开');}

void MainWindow::onTcpReadyRead(){ // 接收服务器数据 QByteArray data = tcpSocket->readAll(); QString suggestion = QString::fromUtf8(data); ui->textEdit->append(suggestion);}

void MainWindow::onTcpError(QAbstractSocket::SocketError socketError){ ui->textEdit->append('连接失败');}

2.3 UI界面

创建一个QPushButton按钮,命名为connectButton,用于连接服务器。

创建一个QTextEdit文本框,用于显示连接状态和服务器建议信息。

3. 数据库 (database.db)

3.1 创建数据库

使用SQLite3工具创建名为database.db的数据库文件。

3.2 创建表结构sql-- 创建用户表CREATE TABLE IF NOT EXISTS users ( uid INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(10), passwd VARCHAR(10));

-- 创建智能家居状态表CREATE TABLE IF NOT EXISTS Status ( sid INTEGER PRIMARY KEY AUTOINCREMENT, uid INTEGER, device_name VARCHAR(10), device_state VARCHAR(10), value VARCHAR(10), mode VARCHAR(10), FOREIGN KEY (uid) REFERENCES users (uid));

4. 运行程序

  1. 编译并运行服务器程序。2. 编译并运行客户端程序。3. 点击客户端界面上的connectButton按钮,连接服务器。4. 客户端将发送用户ID给服务器。5. 服务器根据用户ID查询数据库,分析设备状态,并生成建议信息。6. 服务器将建议信息发送给客户端。7. 客户端在文本框中显示服务器建议信息。

总结

本文介绍了如何使用Linux C语言和QT C++编写一个简单的客户端-服务器程序,并通过SQLite数据库进行数据交互。你可以根据实际需求修改和完善代码,实现更复杂的功能。

Linux C语言服务器与QT C++客户端的TCP通信及SQLite数据库应用

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

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