QT TCP服务器和客户端示例程序

下面是一个简单的 Qt TCP 服务器和客户端示例,演示了如何使用 vSetDrivervSetListenervTcpServerStart 函数。假设 vSetDrivervSetListener 是你定义的自定义函数。

TCP 服务器部分

tcpserver.h
cpp 复制代码
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>

class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit TcpServer(QObject *parent = nullptr);
    void vSetDriver(QObject *driver);
    void vSetListener(QObject *listener);
    void vTcpServerStart(int port);

signals:
    void log(QString message);
    void connected(quint32 addr, int port);
    void disconnected(quint32 addr, int port);
    void recvData(quint32 addr, int port, QByteArray data);

protected:
    void incomingConnection(qintptr socketDescriptor) override;

private slots:
    void onReadyRead();
    void onDisconnected();

private:
    QObject *m_driver;
    QObject *m_listener;
    QTcpSocket *m_socket;
};

#endif // TCPSERVER_H
tcpserver.cpp
cpp 复制代码
#include "tcpserver.h"
#include <QHostAddress>

TcpServer::TcpServer(QObject *parent) : QTcpServer(parent), m_driver(nullptr), m_listener(nullptr), m_socket(nullptr) {}

void TcpServer::vSetDriver(QObject *driver)
{
    m_driver = driver;
}

void TcpServer::vSetListener(QObject *listener)
{
    m_listener = listener;
}

void TcpServer::vTcpServerStart(int port)
{
    if (!this->listen(QHostAddress::Any, port)) {
        emit log("Server could not start!");
    } else {
        emit log("Server started!");
    }
}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{
    m_socket = new QTcpSocket(this);
    connect(m_socket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);
    connect(m_socket, &QTcpSocket::disconnected, this, &TcpServer::onDisconnected);

    m_socket->setSocketDescriptor(socketDescriptor);
    emit connected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
}

void TcpServer::onReadyRead()
{
    QByteArray data = m_socket->readAll();
    emit recvData(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort(), data);
}

void TcpServer::onDisconnected()
{
    emit disconnected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
    m_socket->deleteLater();
}

TCP 客户端部分

tcpclient.h
cpp 复制代码
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QTcpSocket>

class TcpClient : public QObject
{
    Q_OBJECT
public:
    explicit TcpClient(QObject *parent = nullptr);
    void connectToServer(const QString &host, int port);
    void sendData(const QByteArray &data);

signals:
    void log(QString message);
    void connected();
    void disconnected();
    void recvData(QByteArray data);

private slots:
    void onReadyRead();
    void onConnected();
    void onDisconnected();

private:
    QTcpSocket *m_socket;
};

#endif // TCPCLIENT_H
tcpclient.cpp
cpp 复制代码
#include "tcpclient.h"

TcpClient::TcpClient(QObject *parent) : QObject(parent), m_socket(new QTcpSocket(this))
{
    connect(m_socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead);
    connect(m_socket, &QTcpSocket::connected, this, &TcpClient::onConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &TcpClient::onDisconnected);
}

void TcpClient::connectToServer(const QString &host, int port)
{
    m_socket->connectToHost(host, port);
}

void TcpClient::sendData(const QByteArray &data)
{
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->write(data);
    }
}

void TcpClient::onReadyRead()
{
    QByteArray data = m_socket->readAll();
    emit recvData(data);
}

void TcpClient::onConnected()
{
    emit log("Connected to server");
    emit connected();
}

void TcpClient::onDisconnected()
{
    emit log("Disconnected from server");
    emit disconnected();
}

示例主程序

main.cpp
cpp 复制代码
#include <QCoreApplication>
#include "tcpserver.h"
#include "tcpclient.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TcpServer server;
    server.vSetDriver(&server);
    server.vSetListener(&server);
    server.vTcpServerStart(12345);

    TcpClient client;
    client.connectToServer("127.0.0.1", 12345);
    client.sendData("Hello, Server!");

    return a.exec();
}
main.pro
复制代码
QT += core network
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app
SOURCES += main.cpp \
           tcpserver.cpp \
           tcpclient.cpp

HEADERS += tcpserver.h \
           tcpclient.h

解释

  • TcpServer 类:
    • vSetDrivervSetListener 方法用于设置驱动和监听对象。
    • vTcpServerStart 方法用于启动服务器。
    • incomingConnection 方法处理新的连接。
    • onReadyReadonDisconnected 方法分别处理数据接收和连接断开事件。
  • TcpClient 类:
    • connectToServer 方法连接到服务器。
    • sendData 方法发送数据。
    • onReadyReadonConnectedonDisconnected 方法分别处理数据接收、连接和断开事件。
  • 主程序
    • 创建并配置服务器和客户端对象。
    • 客户端连接到服务器并发送数据。

这个示例演示了如何使用 Qt 的网络模块创建一个简单的 TCP 服务器和客户端,并展示了如何通过自定义的 vSetDrivervSetListenervTcpServerStart 方法进行初始化和管理。

如何测试:

1. 准备项目结构

确保项目文件结构正确,并包含以下文件:

  • tcpserver.h
  • tcpserver.cpp
  • tcpclient.h
  • tcpclient.cpp
  • main.cpp
  • myproject.pro

2. 项目配置文件 (myproject.pro)

确保你的项目配置文件 (myproject.pro) 正确配置:

复制代码
QT += core network
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app
SOURCES += main.cpp \
           tcpserver.cpp \
           tcpclient.cpp

HEADERS += tcpserver.h \
           tcpclient.h

3. 编译项目

使用 qmakemake 编译项目。在终端中执行以下命令:

shell 复制代码
qmake myproject.pro
make

4. 运行测试

在编译成功后,运行生成的可执行文件。以下是测试步骤:

4.1 启动服务器

在一个终端中运行服务器部分:

shell 复制代码
./myproject

此时,服务器应该启动并监听端口 12345,等待客户端连接。

4.2 启动客户端

在另一个终端中运行客户端部分:

shell 复制代码
./myproject

此时,客户端应该连接到服务器并发送 "Hello, Server!" 消息。

5. 验证测试结果

检查服务器输出

服务器应该输出类似以下的日志信息:

复制代码
Server started!
connect : 127.0.0.1(12345)
recv : 127.0.0.1(12345)
检查客户端输出

客户端应该输出类似以下的日志信息:

复制代码
Connected to server

6. 修改和扩展

根据需要修改和扩展你的代码。例如,你可以在 recvData 信号处理函数中添加更多的处理逻辑,或者在客户端中添加接收服务器响应的功能。

7. 完整代码示例

tcpserver.h
cpp 复制代码
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>

class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit TcpServer(QObject *parent = nullptr);
    void vSetDriver(QObject *driver);
    void vSetListener(QObject *listener);
    void vTcpServerStart(int port);

signals:
    void log(QString message);
    void connected(quint32 addr, int port);
    void disconnected(quint32 addr, int port);
    void recvData(quint32 addr, int port, QByteArray data);

protected:
    void incomingConnection(qintptr socketDescriptor) override;

private slots:
    void onReadyRead();
    void onDisconnected();

private:
    QObject *m_driver;
    QObject *m_listener;
    QTcpSocket *m_socket;
};

#endif // TCPSERVER_H
tcpserver.cpp
cpp 复制代码
#include "tcpserver.h"
#include <QHostAddress>

TcpServer::TcpServer(QObject *parent) : QTcpServer(parent), m_driver(nullptr), m_listener(nullptr), m_socket(nullptr) {}

void TcpServer::vSetDriver(QObject *driver)
{
    m_driver = driver;
}

void TcpServer::vSetListener(QObject *listener)
{
    m_listener = listener;
}

void TcpServer::vTcpServerStart(int port)
{
    if (!this->listen(QHostAddress::Any, port)) {
        emit log("Server could not start!");
    } else {
        emit log("Server started!");
    }
}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{
    m_socket = new QTcpSocket(this);
    connect(m_socket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);
    connect(m_socket, &QTcpSocket::disconnected, this, &TcpServer::onDisconnected);

    m_socket->setSocketDescriptor(socketDescriptor);
    emit connected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
}

void TcpServer::onReadyRead()
{
    QByteArray data = m_socket->readAll();
    emit recvData(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort(), data);
}

void TcpServer::onDisconnected()
{
    emit disconnected(m_socket->peerAddress().toIPv4Address(), m_socket->peerPort());
    m_socket->deleteLater();
}
tcpclient.h
cpp 复制代码
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QTcpSocket>

class TcpClient : public QObject
{
    Q_OBJECT
public:
    explicit TcpClient(QObject *parent = nullptr);
    void connectToServer(const QString &host, int port);
    void sendData(const QByteArray &data);

signals:
    void log(QString message);
    void connected();
    void disconnected();
    void recvData(QByteArray data);

private slots:
    void onReadyRead();
    void onConnected();
    void onDisconnected();

private:
    QTcpSocket *m_socket;
};

#endif // TCPCLIENT_H
相关推荐
SWAGGY..11 小时前
Linux系统编程:(二)基础指令详解
linux·运维·服务器
螺丝钉的扭矩一瞬间产生高能蛋白12 小时前
QT的C++接口基础用法
c++·qt·嵌入式软件·嵌入式linux·linux应用
蜡笔婧萱12 小时前
Linux--远程登录服务ssh
linux·服务器·ssh
雾岛心情12 小时前
小铭邮件管理工具箱的界面(公司版)
运维·服务器·工具·o365·小铭邮件工具箱(公司版)
伏加特遇上西柚13 小时前
Loki+Alloy+Grafana日志采集部署
java·linux·服务器·spring boot·grafana·prometheus
zl_dfq13 小时前
服务器设计细节 之 【eventfd、struct stat、stat接口】
服务器
资源分享助手13 小时前
三网H5小游戏战车向前冲搭建教程(Win+Linux)
linux·运维·服务器
无限进步_13 小时前
Linux权限模型:从rwx到粘滞位
linux·运维·服务器
似是燕归来13 小时前
WiFi 模块自动联网自带MQTT协议栈和云服务器串口透传免AT开发
服务器·esp32·wifi模块·mqtt协议
Web极客码14 小时前
什么是WHMCS?
服务器·whmcs