QT有封装好的UDP协议的类,QUdpSocket,里面有我们想要的函数接口。感兴趣的话,可以看看。
先搞服务端吧,写一个子类,继承QDialog类,起名为UdpServer类。头文件要引用我们上边说的QUdpSocket这个类,还有我们想要的布局的类。
1 #ifndef UDPSERVER_H 2 #define UDPSERVER_H 3 4 #include <QDialog> 5 #include <QLabel> 6 #include <QLineEdit> 7 #include <QPushButton> 8 #include <QVBoxLayout> 9 #include <QtNetwork/QUdpSocket> 10 #include <QtNetwork/QHostAddress> 11 #include <QTimer> 12 class UdpServer : public QDialog 13 { 14 Q_OBJECT 15 public: 16 UdpServer(QWidget *parent = 0,Qt::WindowFlags f= 0); 17 ~UdpServer(); 18 private: 19 QLabel * TimerLabel; 20 QLineEdit * TextLineEdit; 21 QPushButton* StartBtn; 22 QVBoxLayout * mainLayout; 23 public slots: 24 void StartBtnClicked(); 25 void timeout(); 26 private: 27 int port; 28 bool isStarted; 29 QUdpSocket * udpSocket; 30 QTimer *timer; 31 }; 32 #endif // UDPSERVER_H
在.cpp文件里,我们先是把界面显示出来,然后用udp的writedategram把想要传的写进去。
1 #include "udpserver.h" 2 3 4 UdpServer::UdpServer(QWidget *parent,Qt::WindowFlags f) 5 : QDialog(parent,f) 6 { 7 setWindowTitle(tr("UDP SERVER")); 8 TimerLabel = new QLabel(tr("show time:"),this); 9 TextLineEdit = new QLineEdit(this); 10 StartBtn = new QPushButton(tr("start"),this); 11 12 mainLayout = new QVBoxLayout(this); 13 mainLayout-> addWidget(TimerLabel); 14 mainLayout-> addWidget(TextLineEdit); 15 mainLayout-> addWidget(StartBtn); 16 17 connect(StartBtn,SIGNAL(clicked()),this,SLOT(StartBtnClicked())); 18 port = 5555; 19 isStarted = false; 20 udpSocket = new QUdpSocket(this); 21 timer = new QTimer(this); 22 connect(timer,SIGNAL(timeout()),this,SLOT(timeout())); 23 24 } 25 26 UdpServer::~UdpServer() 27 { 28 29 } 30 void UdpServer::StartBtnClicked() 31 { 32 if(!isStarted) 33 { 34 StartBtn->setText(tr("STOP")); 35 timer->start(1000); 36 isStarted = true; 37 } 38 else 39 { 40 StartBtn->setText(tr("BEGIN")); 41 isStarted = false; 42 timer->stop(); 43 } 44 } 45 void UdpServer::timeout() 46 { 47 QString msg = TextLineEdit->text(); 48 int length=0; 49 if(msg=="") 50 { 51 return; 52 } 53 54 if((length=udpSocket->writeDatagram(msg.toLatin1(),msg.length(),QHostAddress::Broadcast,port))!=msg.length()) 55 { 56 qDebug() << msg.toLatin1(); 57 return; 58 } 59 }
我这里用qDebug把要传的东西打印出来,进行测试,看看是否传过去了。
客户端:
1 #ifndef UDPCLIENT_H 2 #define UDPCLIENT_H 3 #include <QDialog> 4 #include <QVBoxLayout> 5 #include <QTextEdit> 6 #include <QPushButton> 7 #include <QtNetwork/QUdpSocket> 8 class UdpClient : public QDialog 9 { 10 Q_OBJECT 11 public: 12 UdpClient(QWidget *parent = 0); 13 ~UdpClient(); 14 private: 15 QTextEdit* ReceiceTextEdit; 16 QPushButton* CloseBtn; 17 QVBoxLayout* mainLayout; 18 public slots: 19 void CloseBtnClicked(); 20 void dataReceived(); 21 private: 22 int port; 23 QUdpSocket* udpSocket; 24 }; 25 #endif // UDPCLIENT_H
客户端很简单,怎么实现布局,我就不多说了,主要是dataReceive函数。
1 #include "udpclient.h" 2 #include <QMessageBox> 3 #include <QHostAddress> 4 5 6 UdpClient::UdpClient(QWidget *parent) 7 :QDialog(parent) 8 { 9 setWindowTitle("UDP CLIENT"); 10 11 ReceiceTextEdit = new QTextEdit(this); 12 CloseBtn = new QPushButton(tr("Close"),this); 13 14 mainLayout = new QVBoxLayout(this); 15 mainLayout->addWidget(ReceiceTextEdit); 16 mainLayout->addWidget(CloseBtn); 17 18 connect(CloseBtn,SIGNAL(clicked()),this,SLOT(CloseBtnClicked())); 19 20 port =5555; 21 22 udpSocket = new QUdpSocket(this); 23 24 bool result = udpSocket->bind(port); 25 26 if(!result) 27 { 28 QMessageBox::information(this,tr("ERROR"),tr("connect error")); 29 return; 30 } 31 connect(udpSocket,SIGNAL(readyRead()),this,SLOT(dataReceived())); 32 33 } 34 UdpClient:: ~UdpClient() 35 { 36 37 38 } 39 void UdpClient::CloseBtnClicked() 40 { 41 close(); 42 } 43 void UdpClient::dataReceived() 44 { 45 while(udpSocket->hasPendingDatagrams()) 46 { 47 48 QByteArray datagram; 49 datagram.resize(udpSocket->pendingDatagramSize()); 50 udpSocket->readDatagram(datagram.data(),datagram.size()); 51 QString msg=datagram.data(); 52 ReceiceTextEdit->insertPlainText(msg); 53 54 } 55 }
最后显示一下界面,服务端发送hello。
客户端收到的:
不停的在打印hello。直到点击关闭,或者服务端停止。