【Qt开发流程】之TCP

概述

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输协议。它是互联网协议套件中的一部分,用于在网络上可靠地传输数据。

TCP通过建立连接、数据传输和连接终止三个阶段来进行通信。在建立连接阶段,客户端和服务器之间会进行握手,确认彼此的身份并建立一个可靠的连接。在数据传输阶段,数据会被分成小的数据包,每个数据包都包含序列号,接收方会根据序列号对数据包进行排序和重组,以确保数据的正确顺序和完整性。在连接终止阶段,连接会被关闭,释放资源。

TCP提供了可靠的数据传输服务,通过使用确认和重传机制来确保数据的准确性和完整性。它还支持流量控制和拥塞控制机制,以避免网络拥塞和数据丢失。TCP的连接是全双工的,意味着数据可以在两个方向上同时传输。

同时,TCP是一种面向连接的协议,这意味着在进行通信之前,客户端和服务器必须先进行握手建立连接。这种连接的特点是可靠性和顺序性,数据包会按照发送的顺序被接收方接收和处理。

QTcpSocket

QTcpSocket类提供一个TCP套接字。该类继承于QAbstractSocket。

QTcpSocket是异步进行工作的,通过发送信号来报告状态改变和错误信息,依靠事件循环来检测接收的数据。

可以使用QTcpSocket::write()方法写入数据,使用QTCPSocket::read()方法读取数据。

当从一个QTcpSocket中读取数据前,必须先调用QTcpSocket::bytesAvailable()函数来确保已有足够的数据可用。

如果要处理到来的TCP连接,需要使用到QTcpServer类。

QTcpServer

QTcpServer类提供了一个基于tcp的服务器。

这个类使得接受传入的TCP连接成为可能。可以指定端口,也可以让QTcpServer自动选择一个。可以监听一个特定的地址,也可以监听所有机器的地址。

调用listen()让服务器侦听传入的连接。然后,每次客户端连接到服务器时都会发出newConnection()信号。

调用nextPendingConnection()将挂起的连接作为已连接的QTcpSocket接受。该函数返回QAbstractSocket::ConnectedState中指向QTcpSocket的指针,可以使用该指针与客户端进行通信。

如果发生错误,serverError()返回错误的类型,并且可以调用errorString()来获得关于发生的错误描述。

当监听连接时,服务器正在监听的地址和端口可以作为serverAddress()和serverPort()使用。

调用close()使QTcpServer停止侦听传入的连接。

虽然QTcpServer主要是为与事件循环一起使用而设计的,但是不使用事件循环也可以使用它。在这种情况下,必须使用waitForNewConnection(),它会阻塞,直到连接可用或超时过期。

bool QTcpServer::waitForNewConnection(int msec = 0, bool *timedOut = Q_NULLPTR)

最多等待几毫秒,或者直到进入的连接可用为止。如果连接可用,则返回true;否则返回false。如果操作超时且timemedout不为0,则* timemedout将被设置为true。

这是一个阻塞函数调用。不建议在单线程GUI应用程序中使用它,因为整个应用程序将停止响应,直到函数返回。waitForNewConnection()在没有事件循环可用时非常有用。

非阻塞的替代方法是连接到newConnection()信号。

如果msec为-1,则该函数不会超时。

TCP 客户端和服务端连接流程

示例

先上UI

服务端监听,客户端连接,如果成功,服务端发送helloworld,客户端显示
server部分源码

cpp 复制代码
    m_pServer = new QTcpServer(this);
    if(!m_pServer->listen(QHostAddress::LocalHost, 4567))
    {
        QMessageBox::information(this, "prompt", m_pServer->errorString());
        return;
    }
    connect(m_pServer, &QTcpServer::newConnection, this, &MainWindow::slot_sendMsg);
}
void MainWindow::slot_sendMsg()
{
    QByteArray ba("helloworld");

    QTcpSocket* m_pSocket = m_pServer->nextPendingConnection();
    connect(m_pSocket, &QTcpSocket::disconnected, m_pSocket, &QTcpSocket::deleteLater);
    m_pSocket->write(ba, ba.size());
    m_pSocket->disconnectFromHost();
    ui->plainTextEdit->appendPlainText(QString("发送数据 :%1").arg(QString(ba)));
}
  • 解释:
    首先创建一个Server对象,然后监听本地主机的4567端口,如果成功,就发射newConnection()信号
    client部分源码
cpp 复制代码
    m_pSocket = new QTcpSocket(this);


    connect(m_pSocket, &QTcpSocket::readyRead, this, [=](){
        QString strInfo;
        strInfo = m_pSocket->readAll();
        ui->plainTextEdit->appendPlainText(strInfo);
    });
}

void MainWindow::on_toolButton_con_clicked()
{
    m_pSocket->abort();
    m_pSocket->connectToHost(ui->lineEdit->text(), ui->lineEdit_2->text().toShort());
}
  • 解释
    连接本地主机的4567端口,当有可读数据时,发送readyRead()信号。

使用场景

  1. 网页浏览:当用户在浏览器中请求网页时,使用HTTP协议进行通信,而HTTP通常基于TCP协议。TCP确保网页的可靠传输,确保网页内容的准确性和完整性。

  2. 文件传输:当用户需要通过网络传输文件时,常用的协议如FTP(文件传输协议)和SCP(Secure Copy)使用TCP协议。TCP可以确保文件的完整性和准确性。

  3. 电子邮件:SMTP(简单邮件传输协议)和POP3(邮局协议版本3)都使用TCP协议。TCP保证了邮件的可靠传输,以及邮件的正确接收和发送。

  4. 远程登录:如Telnet和SSH(安全外壳)协议使用TCP协议进行远程登录。TCP提供了稳定的连接,确保远程用户的输入和输出可以正确传输。

  5. 数据库访问:在数据库服务器和客户端之间进行数据的传输和交互时,使用TCP协议进行连接和通信。TCP保证了数据的完整性和可靠性。

结论

心有多大,舞台就有多大。

相关推荐
青瓦梦滋6 小时前
WebSocket协议
linux·服务器·网络·c++·websocket·网络协议·http
zhang133830890756 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻7 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
初阳7857 小时前
【基于Qt5仿音乐播放器(六)】——细节打磨与总结
qt·1024程序员节
IpdataCloud8 小时前
批量查IP的API接口怎么选?免费API配额瓶颈与离线库本地批量方案实测
网络·网络协议·tcp/ip
ITyunwei098710 小时前
售后夜间值守怎么落地:从告警到交接的工单系统配置笔记
网络
Smoothcloud润云11 小时前
GPU远程纳管安全吗?最小权限、网络边界与日志审计实战
服务器·网络·人工智能·安全·gpu算力·gpu
ai大模型-探索者11 小时前
Function Call与MCP(区别、联系与实战)
java·服务器·网络
木子欢儿11 小时前
Debian 13 + vsftpd 搭建FTP服务
linux·服务器·前端·网络·debian
达~熊迪12 小时前
IP 分配前核查:把在线状态和使用登记一起看
服务器·网络·tcp/ip