Qt之UDP编程实验(1)

该程序为QT自带Demo,工程名为broadcast receiver,展示了在一个如何在本地局域网中接收UDP广播的信息。

broadcastreceiver.pro

 HEADERS       = receiver.h
 SOURCES       = receiver.cpp \
                 main.cpp
 QT           += network

receiver.h

复制代码

#ifndef RECEIVER_H
#define RECEIVER_H

#include<QWidget>

class QLabel;
class QPushButton;
class QUdpSocket;

class Receiver:public QWidget
{
    Q_OBJECT
public:
    Receiver(QWidget *parent=0);

private slots:
void processPendingDatagrams();

private:
    QLabel *statusLabel;
    QPushButton *quitButton;
    QUdpSocket *udpSocket;
};


#endif // RECEIVER_H

复制代码

receiver.cpp

复制代码

#include<QtGui>
#include<QtNetwork>

#include"receiver.h"

Receiver::Receiver(QWidget *parent):QWidget(parent)
{
    statusLabel=new QLabel(tr("Listening for broadcasted messages"));
    statusLabel->setWordWrap(true);//设置为可换行
    quitButton=new QPushButton(tr("&Quit"));

    udpSocket=new QUdpSocket(this);
    
    /*QUdpSocket::ShareAddress表明其他服务也可以绑定在这个端口上*/
    udpSocket->bind(45454, QUdpSocket::ShareAddress);

    connect(udpSocket,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));
    connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));

    QHBoxLayout *buttonLayout=new QHBoxLayout();
    buttonLayout->addStretch(1);
    buttonLayout->addWidget(quitButton);
    buttonLayout->addStretch(1);

    QVBoxLayout *mainLayout=new QVBoxLayout();
    mainLayout->addWidget(statusLabel);
    mainLayout->addLayout(buttonLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Receiver"));


}

void Receiver::processPendingDatagrams()
{
    while(udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(),datagram.size());
        statusLabel->setText(tr("Received datagram:\"%1\"").arg(datagram.data()));
    }
}

复制代码

main.cpp

复制代码

#include<QApplication>
#include"receiver.h"

int main(int argc,char *argv[])
{
    QApplication app(argc,argv);
    Receiver receiver;
    receiver.show();
    return app.exec();
}

复制代码

 运行结果:

 

一、概述:                                           

#include <QUdpSocket>

QUdpSocket类继承自QAbstractSocket,该类中的所有函数都是可重入的(reentrent)。

 

二、介绍

QUdpSocket描述:

QUdpSocket提供了UDP套接字API,用来接收和发送UDP数据报。

QUdpSocket类最通用的使用方式是:用bind()函数绑定一个IP地址和端口Port,然后调用writeDatagram()和readDatagram()函数传输数据。如果要使用QIODevice中的read(), readLine(), write()等函数,必须首先调用connectToHost()函数,直接建立一个和对方的连接。

 

只要向网络写入了一个数据报,SOCKET就产生一个bytesWritten()信号,如果仅仅是发送数据报,无需调用bind()。

数据报到来,readyRead()信号被产生,此时hasPendingDatagrams()函数返回真(true)。调用pendingDatagramSize()获取第一个数据报的长度(size),readDatagram()读取数据报内容。

 

注意:接收到readyRead()信号后,应当读取该数据报,否则下一个数据报到来后将不再产生readyRead()信号。

 


QUdpSocket类也支持UPD组播(multicast)。joinMulticastGroup()和leaveMulticastGroup()用来控制组成员,QAbstractSocket::MulticastTtlOption和QAbstractSocket::MulticastLoopbackOption分别用来设置socket的TTL和回环(loopback)选项,setMulticastInterface()用来为组播数据报设置对外接口,multicastInterface()来获取该接口类型:IP_MULTICAST_IF对应IPv4,IPV6_MULTICAST_IFIPv6。

 

通过QUdpSocket类,还可以使用connectToHost()建立和UDP服务器的虚拟连接,然后使用read()和write()交换数据,而不必为每一个数据报都指定接收者(receiver)。

 

三、标志成员含义

 

BindFlag:

这些值可以组成不同的标志,传递给QUdpSocket::bind()函数来修改bind()的特性。

enum   BindFlag {ShareAddress, DontShareAddress, ReuseAddressHint, DefaultForPlatform }

 

常量定义描述
QUdpSocket::ShareAddress0x1

1、允许其他服务绑定同样的地址和端口。
2、当多进程通过监听同一地址和端口,进而共享单个服务的负载时。将十分有用(例如:一个拥有几个预先建立的监听者的WEB服务器能够改善响应时间)。不过,由于任何服务都允许重新绑定(rebind),该选项应该引起某些安全上的考虑

3、需要注意的是,把该选项和ReuseAddressHint结合,也会允许你的服务重新绑定一个已存在的共享地址

4、在Unix上,该选项等同于SO_REUSEADDR;在Windows上,该选项被忽略

QUdpSocket::DontShareAddress0x2

1、采用专有的方式绑定某个地址和端口,其他任何服务都不能再重新绑定

2、通过该选项,确保绑定成功,指定的服务将是地址和端口唯一监听者,就算是拥有ReuseAddressHint的服务也不允许重新绑定

3、在安全性上,该选项优于ShareAddress,但是在某些操作系统上需要管理员的权限才能运行

4、在Unix和Mac OS上,绑定地址和端口的默认行为是非共享,所以该选项会被忽略;在Windows上,等同于SO_EXCLUSIVEADDRUSE套接字选项

QUdpSocket::ReuseAddressHint0x4  

1、为QUdpSocke提供提示,即在地址和端口已经被其他套接字绑定的情况下,也应该试着重新绑定

2、在Unix上,该选项被忽略;在Windows上等同于SO_REUSEADDR 套接字选项

QUdpSocket::DefaultForPlatform0x0

1、当前平台的默认选项

2、在Unix和Mac OS上,该选项等同于DontShareAddress + ReuseAddressHint;在Windows上等同于ShareAddress

 

转载自https://www.cnblogs.com/sfy5848/p/4043147.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值