QT的UDP通信编程问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT的UDP通信编程问题相关的知识,希望对你有一定的参考价值。

我用QT写了一个简单的对话程序,实现了类似QQ的两个对话框程序的文字通信,采用的是Qudpsocket。
其中有两句涉及到IP地址:
hostaddr1 = new QHostAddress("1.1.1.1");//不透露信息我随便写的IP
bool conn=udpSocket->bind(*hostaddr1,Port1);//IP是通过百度查的我本机的IP,但我电脑设置的是动态自动获取IP
len=udpSocket->writeDatagram(text.toLatin1(),text.length(),*hostaddr1,Port2);
由于是本机上的两个程序间通话,我程序中的两个IP地址都写得本机,但是无法通信,而且conn变量就是0
但是如果把上述的两个地方都改成QHostAddress::LocalHost,就可以通信了,conn变量也是true,这是为什么啊?为什么我填IP就不对了呢?还是我IP填的方式就不对
正确的实现的效果是下面这样的,两个对话框分别有发送窗口和接受窗口,实现交流对话

参考技术A “由于是本机上的两个程序间通话,我程序中的两个IP地址都写得本机,但是无法通信,而且conn变量就是0”

这里无法通信是指什么,有错误提示吗?

QT网络编程UDP下C/S架构广播通信

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。直到点击关闭,或者服务端停止。

以上是关于QT的UDP通信编程问题的主要内容,如果未能解决你的问题,请参考以下文章

Qt网络编程之搭建Udp通信单播组播广播

QT udp通信如何获取本机IP?

Qt Socket网络编程

qt在windows下的udp通信(最简单)

QT tcp 编程 【在线等】

QT/C++——网络编程