Qt5 C++ TcpSocket 怎样判断是服务主动断开tcp socket连接?

打印 上一主题 下一主题

主题 852|帖子 852|积分 2556

在 Qt 5.9.9 的 C++ 开发中,利用 QTcpSocket 时,要判断是服务端主动断开 TCP Socket 连接,可以通过处置惩罚 QTcpSocket 的 disconnected 信号,结合 QTcpSocket 的状态以及相干事件信息来综合判断。以下是具体的实现思绪和示例代码:
实现思绪


  • 监听 disconnected 信号:当连接断开时,QTcpSocket 会发出 disconnected 信号,我们可以在槽函数中处置惩罚该信号。
  • 检查连接状态:在 disconnected 信号的槽函数中,检查 QTcpSocket 的状态,判断是否为主动断开。可以结合网络错误码、服务端发送的特定消息等举行判断。
  • 服务端主动断开的特征判断:例如,如果服务端在断开连接前发送了特定的关闭消息,客户端吸收到该消息后就可以知道是服务端主动断开;或者通过网络错误码判断是否是服务端正常关闭连接。

示例代码

  1. #include <QtNetwork/QTcpSocket>
  2. #include <QDebug>
  3. #include <QCoreApplication>
  4. class MyTcpClient : public QObject
  5. {
  6.     Q_OBJECT
  7. public:
  8.     MyTcpClient(QObject *parent = nullptr) : QObject(parent)
  9.     {
  10.         socket = new QTcpSocket(this);
  11.         connect(socket, &QTcpSocket::disconnected, this, &MyTcpClient::onDisconnected);
  12.         connect(socket, &QTcpSocket::readyRead, this, &MyTcpClient::onReadyRead);
  13.         // 连接到服务端
  14.         socket->connectToHost("127.0.0.1", 12345);
  15.     }
  16. private slots:
  17.     void onDisconnected()
  18.     {
  19.         // 检查是否是服务端主动断开
  20.         if (socket->state() == QAbstractSocket::UnconnectedState) {
  21.             // 可以进一步根据错误码判断
  22.             if (socket->error() == QAbstractSocket::RemoteHostClosedError) {
  23.                 qDebug() << "Server主动断开连接";
  24.             } else {
  25.                 qDebug() << "连接断开,错误码:" << socket->errorString();
  26.             }
  27.         }
  28.     }
  29.     void onReadyRead()
  30.     {
  31.         QByteArray data = socket->readAll();
  32.         // 假设服务端发送 "CLOSE_CONNECTION" 表示主动断开连接
  33.         if (data == "CLOSE_CONNECTION") {
  34.             qDebug() << "收到服务端断开连接消息,即将断开连接";
  35.             socket->disconnectFromHost();
  36.         }
  37.     }
  38. private:
  39.     QTcpSocket *socket;
  40. };
  41. #include "main.moc"
  42. int main(int argc, char *argv[])
  43. {
  44.     QCoreApplication a(argc, argv);
  45.     MyTcpClient client;
  46.     return a.exec();
  47. }
复制代码
  1. #include <QtNetwork/QTcpServer>
  2. #include <QtNetwork/QTcpSocket>
  3. #include <QDebug>
  4. #include <QCoreApplication>
  5. class MyServer : public QTcpServer
  6. {
  7.     Q_OBJECT
  8. public:
  9.     explicit MyServer(QObject *parent = nullptr) : QTcpServer(parent) {}
  10. protected:
  11.     void incomingConnection(qintptr socketDescriptor) override
  12.     {
  13.         QTcpSocket *socket = new QTcpSocket(this);
  14.         if (!socket->setSocketDescriptor(socketDescriptor)) {
  15.             qDebug() << "Failed to set socket descriptor.";
  16.             delete socket;
  17.             return;
  18.         }
  19.         connect(socket, &QTcpSocket::readyRead, this, [socket]() {
  20.             QByteArray data = socket->readAll();
  21.             qDebug() << "Received from client:" << data;
  22.             // 将收到的数据原样返回给客户端
  23.             socket->write(data);
  24.         });
  25.         connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
  26.     }
  27. };
  28. #include "server.moc"
  29. int main(int argc, char *argv[])
  30. {
  31.     QCoreApplication a(argc, argv);
  32.     MyServer server;
  33.     if (!server.listen(QHostAddress::Any, 12345)) {
  34.         qDebug() << "Server could not start!";
  35.     } else {
  36.         qDebug() << "Server started!";
  37.     }
  38.     return a.exec();
  39. }
复制代码
  1. #include <QtNetwork/QTcpSocket>
  2. #include <QDebug>
  3. #include <QCoreApplication>
  4. int main(int argc, char *argv[])
  5. {
  6.     QCoreApplication a(argc, argv);
  7.     QTcpSocket socket;
  8.     socket.connectToHost(QHostAddress::LocalHost, 12345);
  9.     if (socket.waitForConnected()) {
  10.         qDebug() << "Connected to server!";
  11.         // 向服务器发送消息
  12.         socket.write("Hello, server!");
  13.         socket.waitForBytesWritten();
  14.         if (socket.waitForReadyRead()) {
  15.             QByteArray data = socket.readAll();
  16.             qDebug() << "Received from server:" << data;
  17.         }
  18.     } else {
  19.         qDebug() << "Connection failed!";
  20.     }
  21.     socket.disconnectFromHost();
  22.     if (socket.state() != QAbstractSocket::UnconnectedState) {
  23.         socket.waitForDisconnected();
  24.     }
  25.     return a.exec();
  26. }
复制代码
代码解释


  • MyTcpClient 类:继承自 QObject,封装了 QTcpSocket 对象,用于处置惩罚与服务端的连接。
  • 构造函数:创建 QTcpSocket 对象,并连接 disconnected 和 readyRead 信号到相应的槽函数。然后尝试连接到服务端。
  • onDisconnected 槽函数:在连接断开时被调用,检查 QTcpSocket 的状态和错误码。如果错误码为 QAbstractSocket::RemoteHostClosedError,则表示服务端主动断开连接。
  • onReadyRead 槽函数:在有数据可读时被调用,检查服务端发送的数据。如果收到特定的关闭消息(如 “CLOSE_CONNECTION”),则以为服务端要主动断开连接,调用 disconnectFromHost() 方法断开连接。
重要功能和用法



  • 1 包罗须要的头文件
    在利用 QTcpSocket 之前,需要包罗相应的头文件,并在 .pro 文件中添加 QT += network 以引入网络模块。
  1. #include <QtNetwork/QTcpSocket>
复制代码


  • 2 创建 QTcpSocket 对象
  1. QTcpSocket *socket = new QTcpSocket(this);
复制代码


  • 3 连接到服务器(客户端)
  1. socket->connectToHost(QHostAddress::LocalHost, 12345);
  2. // 可以使用 waitForConnected 等待连接成功
  3. if (socket->waitForConnected()) {
  4.     qDebug() << "Connected to server!";
  5. } else {
  6.     qDebug() << "Connection failed!";
  7. }
复制代码


  • 4.发送数据
  1. QByteArray data = "Hello, server!";
  2. socket->write(data);
  3. // 可以使用 waitForBytesWritten 等待数据发送完成
  4. if (socket->waitForBytesWritten()) {
  5.     qDebug() << "Data sent successfully!";
  6. }
复制代码


  • 5.吸收数据
  1. // 连接 readyRead 信号到槽函数
  2. connect(socket, &QTcpSocket::readyRead, this, [socket]() {
  3.     QByteArray data = socket->readAll();
  4.     qDebug() << "Received data:" << data;
  5. });
复制代码


  • 6.断开连接
  1. socket->disconnectFromHost();
  2. // 可以使用 waitForDisconnected 等待断开连接完成
  3. if (socket->waitForDisconnected()) {
  4.     qDebug() << "Disconnected from server!";
  5. }
复制代码


  • 7.错误处置惩罚
  1. connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
  2.         [](QAbstractSocket::SocketError socketError) {
  3.     qDebug() << "Socket error:" << socketError;
  4. });
  5. // 获取错误信息
  6. qDebug() << "Error message:" << socket->errorString();
复制代码
注意事项



  • 上述示例中的错误码判断和特定消息判断只是一种常见的方式,具体的判断逻辑需要根据实际的业务需求和服务端的实现举行调解。
  • 确保服务端和客户端对断开连接的消息和状态处置惩罚告竣同等,避免出现误解。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

小秦哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表