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

TCP 服务器部分

tcpserver.h
#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
#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
#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
#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
#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 编译项目。在终端中执行以下命令:

qmake myproject.pro
make

4. 运行测试

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

4.1 启动服务器

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

./myproject

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

4.2 启动客户端

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

./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
#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
#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
#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
06-18 11:50