• Qt项目实战--网络编程简单BC端聊天系统


    项目介绍

    基于TCP的客户端聊天系统,客户端连接服务器ip成功后,即可与服务器之间通讯。详细说明见下文。
    在这里插入图片描述

    相关知识点

    开发工具为QT, 具有网络功能的程序需要在pro文件中添加“QT += network”。

    QHostInfo

    QHostInfo类为主机名查找提供了静态函数。这个类提供了两个方便的静态函数:一个异步工作并在找到主机时发出信号另一个阻塞并返回QHostInfo对象。

    异步查找主机的IP地址,调用lookupHost(),它接受主机名或IP地址、接收方对象和槽签名作为参数并返回ID。 您可以通过使用查找ID调用abortHostLookup()来中止查找。

    //通过域名查找ip
    QHostInfo::lookupHost("www.baidu.com",this,[](const QHostInfo& info)
    {
        qDebug()<<info.hostName()<<info.addresses();
    });
    //查找ip是否存在
    QHostInfo::lookupHost("183.232.231.172",this,[](const QHostInfo& info)
    {
        qDebug()<<info.hostName()<<info.addresses();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当结果准备好时,将调用该槽。 结果存储在QHostInfo对象中。 调用addresses()获取主机的IP地址列表,调用hostName()获取所查找的主机名。
    如果查找失败,error()将返回所发生的错误类型。 errorString()给出了可读的查找错误描述。
    要一个阻塞查找,使用QHostInfo::fromName()函数:

    QHostInfo info = QHostInfo::fromName("smtp.qq.com");
    qDebug()<<info.hostName()<<info.addresses();
    
    • 1
    • 2

    QHostAddress

    此类以独立于平台和协议的方式保存IPv4或IPv6地址址.
    在这里插入图片描述

    QAbstractSocket

    QAbstractSocket类提供了所有套接字类型通用的基本功能 。AbstractSocket是QTcpSocket和QUdpSocket的基类,包含这两个类的所有通用功能。

    QTcpSocket

    QTcpSocket类提供一个TCP套接字.

    QTcpSocket *tcpSocket = new QTcpSocket(this);
    tcpSocket->connectToHost("127.0.0.1",8888);
    
    //此信号在调用connectToHost()并成功建立连接后发出。  
    void connected()
    //这个信号在套接字被断开时发出。      
    void disconnected()
    //此信号在发生错误后发出。当发出此信号时,套接字可能还没有准备好重新连接。 在这种情况下,尝试重新连接应该从事件循环中完成。 例如,使用带有0作为超时的QTimer::singleShot()。   
    void error(QAbstractSocket::SocketError socketError)
    //在调用connectToHost()并成功查找主机之后,将发出此信号。    
    void hostFound()
    //每当有新的数据可以从设备的当前读取通道读取时,就会发出此信号。    
    void readyRead()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    QUdpSocket

    UDP(用户数据报协议)是一种轻量级、不可靠、面向数据报、无连接的协议。 当可靠性不重要时,可以使用它。 QUdpSocket是QAbstractSocket的一个子类,允许您发送和接收UDP数据报。

    使用该类最常见的方法是使用bind()绑定到一个地址和端口,然后调用writeDatagram()和readDatagram() / receiveDatagram()来传输数据。 如果你想使用标准的QIODevice函数read(), readLine(), write()等,你必须首先通过调用connectToHost()将套接字直接连接到对等体。
    套接字在每次将数据报写入网络时发出bytesWritten()信号。 如果您只是想发送数据报,则不需要调用bind()。

    readyRead()信号在数据报到达时被触发。 在这种情况下,hasPendingDatagrams()返回true。 调用pendingDatagramSize()获取第一个挂起的数据报的大小,并调用readDatagram()或receiveDatagram()读取它。

    QTcpServer

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

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

    调用listen()让服务器监听传入的连接。 然后,每当客户机连接到服务器时,就会发出newConnection()信号。 调用nextPendingConnection()接受挂起的连接作为已连接的QTcpSocket。 该函数返回一个指向QAbstractSocket::ConnectedState中的QTcpSocket的指针,您可以使用该指针与客户端通信。

    Server::Server(QObject *parent) : QObject(parent)
    {
        m_tcpServer = new QTcpServer(this);
        m_tcpServer->listen(QHostAddress::Any,6666);
        connect(m_tcpServer,&QTcpServer::acceptError,this,&Server::onAcceptError);
        connect(m_tcpServer,&QTcpServer::newConnection,this,&Server::onNewConnection);
    }
    void Server::onAcceptError(QAbstractSocket::SocketError socketErr)
    {
        qDebug()<<"hasError"<<socketErr;
    }
    
    void Server::onNewConnection()
    {
        qDebug()<<"newConnection";
        //获取下一个待处理的连接
        QTcpSocket* tcpSocket = m_tcpServer->nextPendingConnection();
        m_tcps.push_back(tcpSocket);
        tcpSocket->write("hello");
        qDebug()<<m_tcps.size();
        connect(tcpSocket,&QTcpSocket::readyRead,this,&Server::onReadyRead);
    }
    
    void Server::onReadyRead()
    {
        QTcpSocket *tcpsokcet = dynamic_cast<QTcpSocket*>(sender());
        if(tcpsokcet)
        {
             qDebug() <<"server"<<QHostAddress(tcpsokcet->peerAddress().toIPv4Address()).toString()<<tcpsokcet->peerName()<<tcpsokcet->peerPort();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    常用函数
    //服务器开始监听指定addres和port上的连接,有新链接发出newConnection()信号
    bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
    //将下一个挂起的连接作为已连接的QTcpSocket对象返回。  在 newConnection()的槽函数中使用
    virtual QTcpSocket *nextPendingConnection()
    
    
    //当接受新连接导致错误时将发出此信号。 socketError参数描述了发生的错误类型。  
    [signals] void acceptError(QAbstractSocket::SocketError socketError)
    //每当有新连接可用时,就会发出此信号。      
    [signals] void newConnection()   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    项目展示

    项目代码已上传至博客。博客gitee
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    振弦采集模块的通讯速率和软件握手( UART)
    Web自动化测试进阶:网页中难点之等待机制 —— 强制等待,隐式等待
    微信小程序抓包教程:Burpsuite版 附所需工具
    WEB 渗透之文件类操作
    简单分组汇总
    portainer + portainer/agent
    王树森Transformer学习笔记
    苹果ios系统IPA包企业签名手机下载应用可以有几种方式可以下载到手机?
    【面试题 - mysql】进阶篇 - MVCC多版本并发控制原理
    15.NAT实验
  • 原文地址:https://blog.csdn.net/qq_51969153/article/details/126717451