QT客户端和Linux服务器如何连接

不能连接怎么解决呢

img

img

服务器:


// main.c

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

#define PORT 8989

int main() {
    int serverSocket, clientSocket;
    struct sockaddr_in serverAddress, clientAddress;
    socklen_t clientAddressLength = sizeof(clientAddress);

    // 创建套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0) {
        perror("创建套接字出错");
        exit(1);
    }

    // 设置服务器地址
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(PORT);

    // 将套接字绑定到指定的地址和端口
    if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
        perror("绑定套接字出错");
        exit(1);
    }

    // 监听传入连接
    if (listen(serverSocket, 5) < 0) {
        perror("监听连接出错");
        exit(1);
    }

    printf("服务器已启动。正在监听端口 %d...\n", PORT);

    while (true) {
        // 接受客户端连接
        clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);
        if (clientSocket < 0) {
            perror("接受连接出错");
            exit(1);
        }

        printf("客户端已连接,来自 %s:%d\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));

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

        // 关闭客户端连接
        close(clientSocket);
        printf("客户端已断开连接\n");
    }

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

    return 0;
}
===================================================================================================
// server.h

#ifndef SERVER_H
#define SERVER_H

#include <json-c/json.h>

void handleClientRequest(int clientSocket); // 处理客户端请求
void handleTemperatureHumidity(int clientSocket, int uid); // 处理温度湿度请求
void sendResponse(int clientSocket, const char* response); // 发送响应
char* getAdvice(int temperature, int humidity); // 获取建议

#endif
===========================

// server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <json-c/json.h>
#include "server.h"

#define DATABASE "database.db"

struct Status {
    int sid; // 状态ID
    int uid; // 用户ID
    char device_name[10]; // 设备名称
    char device_state[10]; // 设备状态
    char value[10]; // 值
    char mode[10]; // 模式
};

void handleClientRequest(int clientSocket) {
    char buffer[1024];
    int bytesRead = read(clientSocket, buffer, sizeof(buffer));
    if (bytesRead < 0) {
        perror("从套接字读取数据出错");
        exit(1);
    }

    // 解析JSON请求
    struct json_object* jsonRequest = json_tokener_parse(buffer);
    if (jsonRequest == NULL) {
        perror("解析JSON出错");
        exit(1);
    }

    // 从JSON请求中获取用户ID
    struct json_object* jsonUserID;
    json_object_object_get_ex(jsonRequest, "userid", &jsonUserID);
    int uid = json_object_get_int(jsonUserID);

    // 处理温度湿度请求
    handleTemperatureHumidity(clientSocket, uid);

    // 清理资源
    json_object_put(jsonRequest);
}

void handleTemperatureHumidity(int clientSocket, int uid) {
    sqlite3* db;
    int rc = sqlite3_open(DATABASE, &db);
    if (rc != SQLITE_OK) {
        perror("打开数据库出错");
        exit(1);
    }

    char query[100];
    snprintf(query, sizeof(query), "SELECT * FROM Status WHERE uid = %d", uid);

    sqlite3_stmt* stmt;
    rc = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        perror("准备SQL语句出错");
        exit(1);
    }

    // 获取用户的最新温度和湿度值
    int temperature = 0;
    int humidity = 0;

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        struct Status status;
        status.sid = sqlite3_column_int(stmt, 0);
        status.uid = sqlite3_column_int(stmt, 1);
        strcpy(status.device_name, (char*)sqlite3_column_text(stmt, 2));
        strcpy(status.device_state, (char*)sqlite3_column_text(stmt, 3));
        strcpy(status.value, (char*)sqlite3_column_text(stmt, 4));
        strcpy(status.mode, (char*)sqlite3_column_text(stmt, 5));

        if (strcmp(status.device_name, "Temperature") == 0) {
            temperature = atoi(status.value);
        } else if (strcmp(status.device_name, "Humidity") == 0) {
            humidity = atoi(status.value);
        }
    }

    // 根据温度和湿度值获取建议
    char* advice = getAdvice(temperature, humidity);

    // 将建议发送给客户端
    sendResponse(clientSocket, advice);

    // 清理资源
    sqlite3_finalize(stmt);
    sqlite3_close(db);
}

void sendResponse(int clientSocket, const char* response) {
    int bytesWritten = write(clientSocket, response, strlen(response));
    if (bytesWritten < 0) {
        perror("写入套接字出错");
        exit(1);
    }
}

char* getAdvice(int temperature, int humidity) {
    char* advice = (char*)malloc(100);

    if (temperature < 24) {
        snprintf(advice, 100, "温度过低,请将温度调高至 26°C。");
    } else if (humidity < 40 || humidity > 70) {
        snprintf(advice, 100, "湿度过高或过低,请调整湿度水平。");
    } else {
        snprintf(advice, 100, "暂无建议。");
    }

    return advice;
}

客户端

#ifndef PROCESSION_H
#define PROCESSION_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>

namespace Ui {
class Procession;
}

class Procession : public QWidget
{
    Q_OBJECT

public:
    explicit Procession(int userid,QWidget *parent = nullptr);
    ~Procession();
    void processionWidget();

private slots:
    void connectToServer();//和服务器通信
    void handleServerResponse(QNetworkReply *reply);//和服务器连接回应

private:
    Ui::Procession *ui;
    int userid;
    QNetworkAccessManager *networkManager;
};

#endif // PROCESSION_H

#include "procession.h"
#include "ui_procession.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

//通过发送POST请求将用户ID发送到指定的服务器,并将服务器的响应显示在界面上。

Procession::Procession(int userid,QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Procession),
    userid(userid)
{
    ui->setupUi(this);
    processionWidget();
    networkManager = new QNetworkAccessManager(this); // 初始化 networkManager 对象
    connect(ui->connectServerBtn,&QPushButton::clicked,this,[=](){
        ui->message->setText("正在连接中……");
        this->connectToServer();
    });
    connect(networkManager, &QNetworkAccessManager::finished, this, &Procession::handleServerResponse);

}

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

void Procession::processionWidget()
{
    setWindowTitle("服务器通信");
    setAutoFillBackground(true);
    QPalette palette=this->palette();
    QPixmap pixmap(":/user/image/image/net.jpg");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    setPalette(palette);
    setFixedSize(600,400);
}
void Procession::connectToServer()
{
    QJsonObject json;
    json["userid"] = this->userid;

    QJsonDocument doc(json);
    QByteArray postData = doc.toJson();

    QNetworkRequest request(QUrl(ui->serverIP->text()));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    networkManager->post(request, postData);
}

void Procession::handleServerResponse(QNetworkReply *reply)
{
    if (reply->error() == QNetworkReply::NoError) {
            QByteArray response = reply->readAll();
            ui->message->append(response);
        } else {
            ui->message->append("连接失败!");
        }

        reply->deleteLater();
}

你可以在连接失败那行那里打印错误信息:

qDebug() << "Error message:" << reply->errorString();

根据输出的错误信息可以大概知道连接失败的原因,再进行解决

【以下回答由 GPT 生成】

I can help you with connecting a QT client to a Linux server. Based on the information you provided, your server code is written in C and it creates a socket and binds it to a specific address and port. Then it listens for incoming connections and accepts client connections. The problem you are facing is that the connection is not successful, and you want to know how to resolve this issue.

To solve this problem, you can follow these steps:

  1. Check the address and port settings in your server code to ensure they are correct. Make sure the specified address is the IP address of your server, and the port matches the port being used in the QT client.

  2. Check if the server is running and not being blocked by a firewall or other network configuration from accessing the specified port. You can use network tools like Telnet to attempt to connect to the server's IP address and port to see if the connection is successful.

  3. Check your QT client code to ensure it is attempting to connect to the correct server IP address and port. You can use the network library provided by QT to establish a connection to the server and send/receive data.

Please note that these are general troubleshooting steps and the specific solution depends on your environment and code implementation. If you can provide more details and code examples, I can provide more accurate help.



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^