Qt的UDP功能调研-QUdpSocket数据收发
下面是一个简单的教程,实现用Qt的QUdpSocket进行数据收发 ps..我们这里以Qt Creator向导中的基于Widget的窗口程序为基础。在QtCreator中可以如下图创建一个基于Widget的窗口程序 [attachment=233] [attachment=232] 首先,QUdpSocket属于QtNetwork模块,要确认工程文件(.pro)中有下面的语句 然后我们在Qt Designer里面设计一下ui,布局和控件名称大致如下图 [attachment=234] 然后编辑widget.h 首先先包含QUdpSocket的头文件 然后添加1个私有成员和4个槽 - class Widget : public QWidget
- {
- Q_OBJECT
- public:
- explicit Widget(QWidget *parent = 0);
- ~Widget();
- QUdpSocket *conn;
- private slots:
- void onData();
- void onError();
- void on_DoBind_clicked();
- void on_DoSend_clicked();
- private:
- Ui::Widget *ui;
- };
然后写widget.cpp中的首先代码 我们需要包含两个头文件,分别是字符集类和桌面类: 然后是构造函数,完成了设置默认编码(如果你的源文件不是utf8,请自己改一下)、设置窗口标题、将窗口移动到桌面中间 - Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget),conn(0)
- {
- ui->setupUi(this);
- QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
- QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
- this->setWindowTitle(tr("UDP消息发送Demo"));
- QDesktopWidget* desktop = QApplication::desktop();
- move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
- }
收到数据的槽,实现了读取数据报,并显示到文本框上 - void Widget::onData()
- {
- while(conn->hasPendingDatagrams())
- {
- QByteArray data;
- data.resize(conn->pendingDatagramSize());
- QHostAddress sender;
- quint16 senderPort;
- conn->readDatagram(data.data(), data.size(),&sender, &senderPort);
-
- ui->MsgArea->append(tr("收到来自%1:%2的消息 %3").arg(sender.toString()).arg(QString::number(senderPort)).arg(QString(data)));
- }
- }
遇到错误的槽,直接把错误显示到文本框 - void Widget::onError()
- {
- ui->MsgArea->append(tr("发生错误 %1").arg(conn->errorString()));
- }
监听按钮的槽,实现了监听指定端口,如果正在监听,则销毁之前的连接对象,并重新监听新的端口 - void Widget::on_DoBind_clicked()
- {
- if(conn)
- {
- delete conn;
- conn=0;
- }
- conn=new QUdpSocket;
- conn->bind(ui->PortInput->value());
- connect(conn,SIGNAL(readyRead()),this,SLOT(onData()));
- connect(conn,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError()));
- ui->MsgArea->append(tr("正在监听 %1").arg(ui->PortInput->value()));
- }
发送按钮的槽,检查连接对象是否存在,不存在窗体,然后发送数据报并提示在文本框上
- void Widget::on_DoSend_clicked()
- {
- if(!conn)
- conn=new QUdpSocket;
- ui->MsgArea->append(tr("向%1:%2发送 %3").arg(ui->IpInput->text()).arg(ui->PeerPort->value()).arg(ui->MsgInput->text()));
- QByteArray data;
- data.append(ui->MsgInput->text());
- conn->writeDatagram(data,QHostAddress(ui->IpInput->text()),ui->PeerPort->value());
- }
代码到这里结束了, 截图: [attachment=235] [attachment=236] 大体上,上下两部分是分开的,即监听部分和发送部分是可以单独工作的,中间的文本框是共用的
|