UDP就是数据报,不安全,发送只需要指定IP地址和端口号码即可。
发送端:
头文件:
#include <QtGui>
#include <QtNetwork>
一般是在头文件中声明创建变量和槽
private slots:
void startBroadcasting();
void broadcastDatagram();
private:
QUdpSocket *udpSocket;
QTimer *timer;
源文件中需要:
udpSocket = new QUdpSocket(this);
connect(startButton, SIGNAL(clicked()), this, SLOT(startBroadcasting()));
connect(timer, SIGNAL(timeout()), this, SLOT(broadcastDatagram()));
开始广播这个函数开启定时器
void Sender::startBroadcasting()
{
startButton->setEnabled(false);
timer->start(1000);
}
广播信息这个函数实现信息发送:
void Sender::broadcastDatagram()
{
QByteArray datagram = "Broadcast message! " ;//
udpSocket->writeDatagram(datagram.data(), datagram.size(),
QHostAddress::Broadcast, 45454);
}
接下来我们来研究一下QHostAddress这个类的含义
他有几个类举值
enum SpecialAddress { Null, LocalHost, LocalHostIPv6, Broadcast, Any, AnyIPv6 }
公共方法有:
QHostAddress ()
QHostAddress ( quint32 ip4Addr )
QHostAddress ( quint8 * ip6Addr )
QHostAddress ( const Q_IPV6ADDR & ip6Addr )
QHostAddress ( const sockaddr * sockaddr )
QHostAddress ( const QString & address )
QHostAddress ( const QHostAddress & address )
QHostAddress ( SpecialAddress address )
接收端:
接收端的编程主要是监听端口,读取值。
头文件定义槽和变量
private slots:
void processPendingDatagrams();
private:
QUdpSocket *udpSocket;
源文件中需要:
udpSocket = new QUdpSocket(this);
udpSocket->bind(45454);
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
数据一旦准备好,就能够进行读取操作。
先检测是否有数据,然后更新数组的大小,读取数据包。
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()));
}
}
数据包的两个重要的域就是.data()和.size()。
其中若是需要获取发来信息的主机IP和端口号,可以使用
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
QUdpSocket类的主要方法有:
QUdpSocket ( QObject * parent = 0 )
virtual ~QUdpSocket ()
bool bind ( const QHostAddress & address, quint16 port )
bool bind ( const QHostAddress & address, quint16 port, BindMode mode )
bool bind ( quint16 port = 0 )
bool bind ( quint16 port, BindMode mode )
bool hasPendingDatagrams () const
bool joinMulticastGroup ( const QHostAddress & groupAddress )
bool joinMulticastGroup ( const QHostAddress & groupAddress, const QNetworkInterface & iface )
bool leaveMulticastGroup ( const QHostAddress & groupAddress )
bool leaveMulticastGroup ( const QHostAddress & groupAddress, const QNetworkInterface & iface )
QNetworkInterface multicastInterface () const
qint64 pendingDatagramSize () const
qint64 readDatagram ( char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0 )
void setMulticastInterface ( const QNetworkInterface & iface )
qint64 writeDatagram ( const char * data, qint64 size, const QHostAddress & address, quint16 port )
qint64 writeDatagram ( const QByteArray & datagram, const QHostAddress & host, quint16 port )
下面对几个比较常用的方法进行说明:
bool QUdpSocket::bind ( const QHostAddress & address, quint16 port )监听指定客户端IP
bool QUdpSocket::bind ( quint16 port = 0 )监听任意IP和指定端口。
bool QUdpSocket::hasPendingDatagrams () const 有缓冲数据包就返回是,不然返回否。
qint64 QUdpSocket::pendingDatagramSize () const 返回第一个等待的UDP数据包,假如没有返回-1
qint64 QUdpSocket::readDatagram ( char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0 )
读取数据包,其中能够获取数据,还有IP,端口等信息,都是在包里获取的。返回读取的包大小,否则返回-1
读取的时候,若是maxSize太小了,后面的信息就会丢失,所以采用pendingDatagramSize方法来获取大小。
qint64 QUdpSocket::writeDatagram ( const char * data, qint64 size, const QHostAddress & address, quint16 port )
qint64 QUdpSocket::writeDatagram ( const QByteArray & datagram, const QHostAddress & host, quint16 port )
写入也是同样的道理,返回的是成功的大小,失败就返回-1.。写入数据不要太大,最好小于512个字节。