下面是一个简单的 Qt TCP 服务器和客户端示例,演示了如何使用 vSetDriver
、vSetListener
和 vTcpServerStart
函数。假设 vSetDriver
和 vSetListener
是你定义的自定义函数。
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 类:
vSetDriver
和vSetListener
方法用于设置驱动和监听对象。vTcpServerStart
方法用于启动服务器。incomingConnection
方法处理新的连接。onReadyRead
和onDisconnected
方法分别处理数据接收和连接断开事件。
- TcpClient 类:
connectToServer
方法连接到服务器。sendData
方法发送数据。onReadyRead
、onConnected
和onDisconnected
方法分别处理数据接收、连接和断开事件。
- 主程序:
- 创建并配置服务器和客户端对象。
- 客户端连接到服务器并发送数据。
这个示例演示了如何使用 Qt 的网络模块创建一个简单的 TCP 服务器和客户端,并展示了如何通过自定义的 vSetDriver
、vSetListener
和 vTcpServerStart
方法进行初始化和管理。
如何测试:
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. 编译项目
使用 qmake
和 make
编译项目。在终端中执行以下命令:
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