Qt的网络连接方式

引入

Qt支持广泛的网络通信方式,包括HTTP/TP协议、TCP连接、UDP连接等等,都可以在Qt netWork模块中实现;

.pro文件中加上QT += network就可以直接使用这个模块了

而且Qt是支持C++11的原生写法的,所以C++原生的很多库也能用,你甚至可以直接写socket连接;

network模块的类的布局

命名空间:

命名说明
QPasswordDigestor包含可用于生成哈希或键的函数
QSsl声明Qt网络中所有SSL类通用的枚举

类成员:

命名说明
QAbstractNetworkCache缓存实现的接口
QAbstractSocket所有套接字类型通用的基本功能
QAuthenticator身份验证对象
QDns域名记录,存储有关域名记录的信息
QDnsHostAddressRecord存储有关主机地址记录的信息
QDnsLookup表示 DNS 查找
QDnsMailExchangeRecord存储有关 DNS MX 记录的信息
QDnsServiceRecord存储有关 DNS SRV 记录的信息
QDnsTextRecord存储有关 DNS TXT 记录的信息
QDtls此类为 UDP 套接字提供加密
QDtlsClientVerifier此类实现服务器端 DTLS Cookie 生成和验证
QDtls此类定义 DTLS Cookie 生成器的参数
QHost地址IP地址
QHostInfo用于主机名查找的静态函数
QHstsPolicy指定主机支持 HTTP 严格传输安全策略 (HSTS)
QHttp2配置控制 HTTP/2 参数和设置
QHttpMultiPart类似于要通过 HTTP 发送的 MIME 多部分消息
QHttpPart保存要在 HTTP 多部分 MIME 消息中使用的正文部分
QLocalServer基于本地套接字的服务器
QLocalSocket本地套接字
QNetworkAccessManager允许应用程序发送网络请求和接收答复
QNetworkAddressEntry存储网络接口支持的一个 IP 地址及其关联的网络掩码和广播地址
QNetworkCacheMetaData缓存信息
QNetworkCookie保存一个网络 Cookie
QNetworkCookieJar实现了一个简单的 QNetworkCookie 对象罐
QNetworkDatagramUDP 数据报的数据和元数据
QNetworkDiskCache非常基本的磁盘缓存
QNetworkInterface主机的 IP 地址和网络接口列表
QNetworkProxy网络层代理
QNetworkProxyFactory细粒度代理选择
QNetworkProxyQuery用于查询套接字的代理设置
QNetworkReply包含使用 QNetworkAccessManager 发送的请求的数据和标头
QNetworkRequest保存要使用 QNetworkAccessManager 发送的请求
QOcspResponse此类表示联机证书状态协议响应
QSctpServer基于 SCTP 的服务器
QSctpSocketSCTP 插座
QSslCertificate用于 X509 证书的便捷 API
QSslCertificateExtension用于访问 X509 证书扩展的 API
QSslCipher表示 SSL 加密密码
QSslConfiguration保存 SSL 连接的配置和状态
QSslDiffieHellmanParameters用于服务器的 Diffie-Hellman 参数接口
QSslEllipticCurve表示供椭圆曲线密码算法使用的椭圆曲线
QSslError断续器错误
QSslKey私钥和公钥接口
QSslPreSharedKeyAuthenticator预共享密钥 (PSK) 密码套件的身份验证数据
QSslSocket客户端和服务器的 SSL 加密套接字
QTcpServer基于 TCP 的服务器
QTcpSocketTCP 套接字
QUdpSocketUDP 插座

虽然Qt提供了这么多的类供我们使用,但在实际项目中我们不会用到这么多的接口类,也不用专门去记它,用的时候查一查,经常用的就那么几个,
接下来我们来看看一般的使用方法和常用的几个接口类。

网络接口信息获取

QNetwork提供 Q H o s t I n f o QHostInfo QHostInfo类提供的静态函数,进行主机名的查找,使用OS提供的查找机制获取一个与主机名关联的IP地址或者获取一个IP地址关联的主机名

QHostInfo中的静态函数 f r o m N a m e ( ) fromName() fromName()(会阻塞并返回QHostInfo一个对象,这个对象的address函数可以获取其主机的IP地址列表)

l o o k u p H o s t lookupHost lookupHost(异步获取,每找到主机就会发送信号)可以进行主机信息的获取

主要应用代码如下:

  //QHostInfo 获取主机名查找
    QString localHostName = QHostInfo::localHostName();//获取了本地主机名

//通过获取主机名 然后两种方式获取其IP地址

    //fromName 寻找主机信息
    QHostInfo info = QHostInfo::fromName(localHostName);
    info.addresses();//获取与主机名相关的IP地址列表 包含了ipv4与ipv6

    //lookupHost查找IP地址
    QHostInfo::lookupHost(localHostName, this, SLOT(lookedUp(QHostInfo)));  
	
void MainWindow::lookedUp(const QHostInfo &host)  //对应的槽函数
{
    if (host.error() != QHostInfo::NoError) {  //先判断是否出错
        qDebug() << "Lookup failed:" << host.errorString();
        return;
    }
    foreach (const QHostAddress &address, host.addresses()) //获取地址
        qDebug() << "Found address:" << address.toString();
}

提供了 Q N e t w o r k I n t e r f a c e QNetworkInterface QNetworkInterface类获取主机的IP地址列表和网络接口信息。

Q N e t w o r k I n t e r f a c e QNetworkInterface QNetworkInterface类代表了运行当前程序的主机的网络接口

// 获取所有网络接口的列表
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    // 遍历每一个网络接口
    foreach (QNetworkInterface interface, list)
    {
        // 接口名称
        qDebug() << "Name: " << interface.name();
        // 硬件地址
        qDebug() << "HardwareAddress: " << interface.hardwareAddress();
        //可以通过它获取所有ip地址
        qDebug()<< "Ip address"<<interface.allAddresses();
        // 获取IP地址条目列表,每个条目中包含一个IP地址,一个子网掩码和一个广播地址
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();//addressEntries()可以返回一个QNetworkAddressEntry对象的列表
        //QNetworkAddressEntry类保存了一个网络支持的IP 以及该IP地址相关的子网掩码和广播地址
        // 遍历每一个IP地址条目
        foreach (QNetworkAddressEntry entry, entryList)
        {
            // IP地址
            qDebug() << "IP Address: " << entry.ip().toString();
            // 子网掩码
            qDebug() << "Netmask: " << entry.netmask().toString();
            // 广播地址
            qDebug() << "Broadcast: " << entry.broadcast().toString();
        }
    }

UDP连接

这种方式最简单,数据包发过去就好了,也不需要他回复,不用管这个数据包到底有没有送到,是一种不可靠的连接方式

发送端:

 QUdpSocket *sender;
    sender = new QUdpSocket(this);
    
    QByteArray datagram = "hello world!";
    sender->writeDatagram(datagram.data(), datagram.size(),QHostAddress::Broadcast, 45454); //广播地址   端口号
    //参数分别为: 数据,数据长度,主机地址,端口号为address的主机的port端口
    //意义是发送size大小的数据包data到地址
    //不建议发送大于512字节的数据报;端口号最好取1024以上的,最大为65535 2的16次方

接收端:

 QUdpSocket *sender;
    receiver = new QUdpSocket(this);
    receiver->bind(45454, QUdpSocket::ShareAddress);//和发送端端口号一致  不需指定IP。默认支持所有IPV4,绑定模式表明允许其他服务器
    //每当有数据报来时,都会触发readyRead()
    connect(receiver, SIGNAL(readyRead()), this, SLOT(processPendingDatagram()));

// 处理等待的数据报
void Receiver::processPendingDatagram()
{
    // 拥有等待的数据报
    while(receiver->hasPendingDatagrams())    //hasPendingDatagrams()判断是否还有等待的数据报
    {
        QByteArray datagram;
        // 让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据
        datagram.resize(receiver->pendingDatagramSize());//pendingDatagramSize() 当前数据包大小
        // 接收数据报,将其存放到datagram中
        receiver->readDatagram(datagram.data(), datagram.size());//readDatagram将不大于指定长度的数据保存到datagram.data()
        ui->label->setText(datagram);
    }
}

TCP连接

TCP连接就是面向数据流和连接的可靠传输协议了,学了计网的对这个都熟悉,我们使用接口类写连接就不需要我们自己用socket手怼三次握手和四次挥手了

服务端

建立连接:

服务端不主动建立连接,他是监听连接的端口,有客户端发送过来的连接请求才会跟他建立全双工连接

先创建一个QTcpServer对象QTcpServer tcp_server;

开启TCP服务器,监听所有地址,端口号:
(监听哪个单独的端口大家再详细看函数的参数列表)

tcp_server.listen(QHostAddress::Any,port);

客户端向服务器发送连接请求时,发送的信号处理的槽函数:

connect(&tcpserver,SLGNAL(newConnection()),this,SLOT(answerConnection()自定义槽函数));

void answerConnection()
{
    //获取和客户端通信的套接字
    QTcpServer* client_socket = tcp_server.nextPendingConnection();
    //保存客户端套接字
    client_list.append(client_socket);
    //客户端向服务器发送消息时,触发readyread信号
    connect(client_socket,SIGNAL,(readyread()),this,SLOT(answerReadyread()));
}

接收客户端发来的信息:

void answerReadyread()
{
    //遍历检查哪个客户端有消息
    for(int i = 0;i < client_list.size();i++)
    {
        //获取等待套接字字节数,没有消息返回0
        if(client_list.at[i]->bytesAvailable())
        {
            QByteArray buf = client_list.at(i)->readALL();//读取保存到buf
            ui->listWidget->addItem(buf);//显示到界面
            sendMessage(buf);//发送给其他客户端
        }
    }
}

客户端

建立连接:

QTcpSocket tcp_socket;//创建和服务器通信的套接字
 
tcp_socket.connectToHost(server_ip,server_port);//向服务器发送连接请求
 
//向服务器发送连接时会发送信号connected
 
connect(&tcp_socket,SIGNAL(connected()),this,SLOT(answerConnected()));
 
//收到服务器转发消息时会发送readyRead()信号
 
connect(&tcp_socket,SIGNAL(readyRead()),this,SLOT(answerReadyRead()));

接收消息:

void answerReadyRead()
{
    if(tcp_socket.bytesAvailable())//如果有消息
    {
        QByteArray buf = tcp_socket.readAll();//将消息内容读出来
        ui->listWidget->addItem(buf);//做什么操作就是看业务需求了
    }
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertOS

还会有大爷会打钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值