服务端
#include "widget.h"
#include <QApplication>
#include <QString>
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QNetworkInterface>
#include <QDebug>
#include <QUdpSocket>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QUdpSocket *sender = new QUdpSocket;
QByteArray datagram = "hello world!";
sender->writeDatagram(datagram.data(),datagram.size(), QHostAddress::Broadcast,45454);
return a.exec();
}
这里定义了一个QByteArray
类型的数据报datagram
,其内容为“hello world!”。然后我们使用QUdpSocket
类的writeDatagram()
函数来发送数据报,这个函数有四个参数,分别是数据报的内容,数据报的大小,主机地址和端口号。对于数据报的大小,它根据平台的不同而不同,但是这里建议不要超过512字节。这里使用了广播地址QHostAddress::Broadcast
,这样就可以同时给网络中所有的主机发送数据报了。对于端口号,它是可以随意指定的,但是一般1024以下的端口号通常属于保留端口号,所以我们最好使用大于1024的端口,最大为65535。我们这里使用了45454这个端口号,一定要注意,在下面要讲的服务器程序中,也要使用相同的端口号。
客户端:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QNetworkInterface>
#include <QDebug>
#include <QUdpSocket>
#include <QByteArray>
#include <QLabel>
#include <QLayout>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
QUdpSocket *m_UDPReceiver;
QLabel *m_textLabel;
public slots:
void processPendingDatagram();
};
#endif // WIDGET_H
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
m_UDPReceiver = new QUdpSocket(this);
m_UDPReceiver->bind(45454,QUdpSocket::ShareAddress);
connect(m_UDPReceiver,SIGNAL(readyRead()),this,SLOT(processPendingDatagram()));
m_textLabel = new QLabel(this);
resize(600,600);
QHBoxLayout *mainHBLayout = new QHBoxLayout(this);
mainHBLayout->addWidget(m_textLabel);
}
Widget::~Widget()
{
}
void Widget::processPendingDatagram()
{
while(m_UDPReceiver->hasPendingDatagrams()) //拥有等待的数据报
{
QByteArray datagram; //拥于存放接收的数据报
//让datagram的大小为等待处理的数据报的大小,这样才能接收到完整的数据
datagram.resize(m_UDPReceiver->pendingDatagramSize());
//接收数据报,将其存放到datagram中
m_UDPReceiver->readDatagram(datagram.data(),datagram.size());
//将数据报内容显示出来
m_textLabel->setText(datagram);
}
}
我们在构造函数中将receiver
绑定到45454端口,这个端口就是上面发送端设置的端口,二者必须一样才能保证接收到数据报。这里使用了绑定模式QUdpSocket::ShareAddress
,它表明其他服务也可以绑定到这个端口上。因为当receiver
发现有数据报到达时就会发出readyRead()
信号,所以将其和数据报处理函数相关联。