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
相关推荐
扣得君1 小时前
C++20 Coroutine Echo Server
运维·服务器·c++20
yyqzjw2 小时前
【qt】控件篇(Enable|geometry)
开发语言·qt
csdn_kike2 小时前
QT Unknown module(s) in QT 以及maintenance tool的更详细用法(qt6.6.0)
开发语言·qt
西西弗Sisyphus2 小时前
Qt 获取当前系统中连接的所有USB设备的信息 lsusb版
qt
keep__go2 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求2 小时前
Linux中给普通账户一次性提权
linux·运维·服务器
jieshenai2 小时前
使用VSCode远程连接服务器并解决Neo4j无法登陆问题
服务器·vscode·neo4j
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss
Gentle5862 小时前
labview连接sql server数据库
服务器·数据库·labview
co0t3 小时前
计算机网络(11)和流量控制补充
服务器·网络·计算机网络