Qt开发:QTcpServer的详解

一、QTcpServer 简介

  QTcpServer 是 Qt 网络模块中的一个核心类,用于实现 基于 TCP 协议的服务端(Server),它负责监听端口、接收客户端连接请求,并通过 QTcpSocket 与客户端通信。

头文件:

#include <QTcpServer>
#include <QTcpSocket>

所属模块:

QT += network

二、常用成员函数的使用

2.1 void close()

作用:

  • 停止当前的监听;
  • 不再接受新的客户端连接;
  • 但 不会主动断开已连接的客户端(你需要自行关闭相关的 QTcpSocket);

使用方式:

QTcpServer server;

// 启动监听
server.listen(QHostAddress::Any, 12345);

// 停止监听
server.close();

调用 close() 后,服务器不再监听新的连接。如果要重新监听,可以再次调用 listen()。

配合判断函数使用:

if (server.isListening()) {
   
   
    server.close();
    qDebug() << "Server closed.";
}

注意事项:

  • close() 只是关闭监听端口,不会自动关闭通过 nextPendingConnection() 创建的 QTcpSocket;
  • 如果要释放所有资源,应在 close() 之后手动删除或管理已连接的 socket。

2.2 QString errorString() const

作用:

  • 当 QTcpServer::listen() 调用失败时,可以使用 errorString() 获取失败原因;
  • 返回值是一个用户可读的字符串(QString),便于调试或显示在日志/界面中;
  • 不适用于成功的监听,仅在发生错误时有效。

典型用法示例:

QTcpServer server;
if (!server.listen(QHostAddress::Any, 12345)) {
   
   
    qDebug() << "Server failed to start:" << server.errorString();
} else {
   
   
    qDebug() << "Server started on port" << server.serverPort();
}

常见输出示例:

  • “The address is already in use”(端口已被占用)
  • “Permission denied”(在受限端口启动服务)
  • “Operation not permitted”(无权限)
  • “Unknown error”

2.3 virtual bool hasPendingConnections() const

作用:

  • 返回 true 表示有客户端连接已到达,但尚未被你用 nextPendingConnection() 拿出来;
  • 返回 false 表示当前没有等待处理的连接;
  • 常配合 nextPendingConnection() 使用,用于服务器主动轮询处理连接(非 newConnection 信号方式)。

常见使用场景:
场景 1:在主循环或定时器中轮询客户端连接

if (server.hasPendingConnections()) {
   
   
    QTcpSocket* clientSocket = server.nextPendingConnection();
    // 处理 socket...
}

场景 2:与 newConnection 信号搭配,增强安全性(防止 nextPendingConnection 为 nullptr)

void MyServer::onNewConnection() {
   
   
    while (server.hasPendingConnections()) {
   
   
        QTcpSocket* socket = server.nextPendingConnection();
        if (socket) {
   
   
            connect(socket, &QTcpSocket::readyRead, this, &MyServer::onReadyRead);
        }
    }
}

完整使用示例:

QTcpServer server;
server.listen(QHostAddress::Any, 12345);

QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, [&]() {
   
   
    while (server.hasPendingConnections()) {
   
   
        QTcpSocket* socket = server.nextPendingConnection();
        qDebug() << "New client:" << socket->peerAddress();
        connect(socket, &QTcpSocket::readyRead, [socket]() {
   
   
            qDebug() << "Data:" << socket->readAll();
        });
    }
});
timer->start(100); // 每 100ms 检查新连接

2.4 bool isListening() const

作用:

  • 返回 true 表示服务器已经成功调用 listen() 并正在监听端口;
  • 返回 false 表示服务器当前未监听任何端口,例如尚未调用 listen(),或者已调用了 close() 停止监听。

使用示例:
示例 1:启动服务器前判断状态

if (!server.isListening()) {
   
   
    if (!server.listen(QHostAddress::Any, 12345)) {
   
   
        qDebug() << "Failed to listen:" << server.errorString();
    } else {
   
   
        qDebug() << "Server started.";
    }
}

示例 2:停止监听前判断是否正在监听

if (server.isListening()) {
   
   
    server.close();
    qDebug() << "Server stopped.";
}

2.5 bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)

作用:

  • 在指定 IP 地址和端口上开启监听;
  • 等待客户端连接(触发 newConnection() 信号);
  • 返回 true 表示监听成功,false 表示失败(可配合 errorString() 查看原因)。

使用示例:
示例 1:监听所有网卡的 12345 端口

QTcpServer server;
if (!server.listen(QHostAddress::Any, 12345)) {
   
   
    qDebug() << "Listen failed:" << server.errorString();
} else {
   
   
    qDebug() << "Server started on port" << server.serverPort();
}

示例 2:监听本机(127.0.0.1)

server.listen(QHostAddress::LocalHost, 9999);

监听成功后该做什么?
连接 newConnection() 信号:

connect(&server, &QTcpServer::newConnection, [&]() {
   
   
    QTcpSocket *client 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值