feat: UDP 的的单播和广播功能已经完全实现了

This commit is contained in:
touwoyimuli 2019-12-02 00:00:56 +08:00
parent 5639919440
commit 488485ee49
4 changed files with 169 additions and 12 deletions

View File

@ -22,35 +22,165 @@
#include "ExTrans.h"
#include "ui_ExTrans.h"
#include <QHostInfo>
ExTrans::ExTrans(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ExTrans)
{
ui->setupUi(this);
setWindowTitle("Tcp通信unicast(单播) + broadcast(广播)的使用");
QString hostName = QHostInfo::localHostName();
QString ip = getLocalIp();
ui->plainTextEdit->appendPlainText("主机名称:" + hostName + "\n主机IP" + ip + "\n");
m_labSocketState = new QLabel("Socket状态");
m_labSocketState->setMinimumWidth(200);
ui->statusBar->addWidget(m_labSocketState);
ui->comboBoxIp->addItem(getLocalIp());
m_udpSocket = new QUdpSocket(this);
connect(m_udpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
onSocketStateChange(m_udpSocket->state());
connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
}
ExTrans::~ExTrans()
{
delete ui;
}
//绑定端口
void ExTrans::on_actBind_triggered()
{
quint16 port = ui->spinBoxBind->value(); //本机UDP端口
if (m_udpSocket->bind(port)) { //端口绑定成功
ui->plainTextEdit->appendPlainText("端口绑定成功:" + QString::number(m_udpSocket->localPort()));
ui->actBind->setEnabled(false);
ui->actDisbind->setEnabled(true);
} else {
ui->plainTextEdit->appendPlainText("端口绑定失败");
}
}
//解除绑定
void ExTrans::on_actDisbind_triggered()
{
m_udpSocket->abort(); //断开,中止套接字
ui->plainTextEdit->appendPlainText("端口解除绑定成功");
ui->actBind->setEnabled(true);
ui->actDisbind->setEnabled(false);
}
//清除文本信息
void ExTrans::on_actClean_triggered()
{
ui->plainTextEdit->clear();
}
//关闭程序
void ExTrans::on_actQuit_triggered()
{
close();
}
//单播消息
void ExTrans::on_btnUnicast_clicked()
{
QString targetIp = ui->comboBoxIp->currentText();
QHostAddress targetAddr(targetIp); //目标 Ip
quint16 targetPort = ui->spinBoxPort->value(); //目标 port
QString msg = ui->lineEdit->text(); //发送的消息
QByteArray str = msg.toUtf8();
m_udpSocket->writeDatagram(str, targetAddr, targetPort); //发送数据报
ui->plainTextEdit->appendPlainText(QString("[Send: ] %1").arg(msg));
ui->lineEdit->clear();
ui->lineEdit->setFocus();
}
//广播消息
void ExTrans::on_btnBroadcast_clicked()
{
quint16 targetPort = ui->spinBoxPort->value(); //目标 port
QString msg = ui->lineEdit->text(); //发送的消息
QByteArray str = msg.toUtf8();
m_udpSocket->writeDatagram(str, QHostAddress::Broadcast, targetPort); //发送 数据报 给所有IP
ui->plainTextEdit->appendPlainText(QString("[广播: ] %1").arg(msg));
ui->lineEdit->clear();
ui->lineEdit->setFocus();
}
//socket 状态发生变化
void ExTrans::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
switch (socketState) {
case QAbstractSocket::UnconnectedState:
m_labSocketState->setText("socket状态UnconnectedState");
break;
case QAbstractSocket::HostLookupState:
m_labSocketState->setText("socket状态HostLookupState");
break;
case QAbstractSocket::ConnectingState:
m_labSocketState->setText("socket状态ConnectingState");
break;
case QAbstractSocket::ConnectedState:
m_labSocketState->setText("socket状态ConnectedState");
break;
case QAbstractSocket::BoundState:
m_labSocketState->setText("socket状态BoundState");
break;
case QAbstractSocket::ClosingState:
m_labSocketState->setText("socket状态ClosingState");
break;
case QAbstractSocket::ListeningState:
m_labSocketState->setText("socket状态ListeningState");
break;
default:
m_labSocketState->setText("socket状态其他未知状态...");
break;
}
}
//读取 socket 传入的数据
void ExTrans::onSocketReadyRead()
{
while (m_udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(m_udpSocket->pendingDatagramSize());
QHostAddress peerAddr;
quint16 peerPort;
m_udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddr, &peerPort); //读取数据包,消息+来自的Ip和port
QString str = datagram.data();
QString peer = QString("[From: %1 %2] %3").arg(peerAddr.toString()).arg(QString::number(peerPort)).arg(str);
ui->plainTextEdit->appendPlainText(peer);
}
}
//获取本机IP
QString ExTrans::getLocalIp()
{
QString hostName = QHostInfo::localHostName();
QHostInfo hostInfo = QHostInfo::fromName(hostName);
QString Ip = "";
if (hostInfo.addresses().isEmpty())
return 0;
foreach (QHostAddress addr, hostInfo.addresses()) {
if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
Ip = addr.toString();
break;
}
}
return Ip;
}

View File

@ -23,11 +23,20 @@
#define EXTRANS_H
#include <QMainWindow>
#include <QLabel>
#include <QUdpSocket>
#include <QString>
namespace Ui {
class ExTrans;
}
/*!
* \class ExTrans UDP的Deam测试广
* \brief IP相同
* 使使IP
*/
class ExTrans : public QMainWindow
{
Q_OBJECT
@ -37,13 +46,24 @@ public:
~ExTrans();
private slots:
void on_actBind_triggered();
void on_actDisbind_triggered();
void on_actClean_triggered();
void on_actQuit_triggered();
void on_actBind_triggered(); //绑定端口
void on_actDisbind_triggered(); //解除绑定
void on_actClean_triggered(); //清除文本信息
void on_actQuit_triggered(); //关闭程序
void on_btnUnicast_clicked(); //单播消息
void on_btnBroadcast_clicked(); //广播消息
void onSocketStateChange(QAbstractSocket::SocketState socketState); //socket 状态发生变化
void onSocketReadyRead(); //读取 socket 传入的数据
private:
QString getLocalIp(); //获取本机IP
private:
Ui::ExTrans *ui;
QLabel* m_labSocketState;
QUdpSocket* m_udpSocket;
};
#endif // EXTRANS_H

View File

@ -4,7 +4,7 @@
#
#-------------------------------------------------
QT += core gui
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

View File

@ -27,7 +27,7 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox">
<widget class="QSpinBox" name="spinBoxBind">
<property name="maximum">
<number>65000</number>
</property>
@ -48,7 +48,14 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox"/>
<widget class="QComboBox" name="comboBoxIp">
<property name="editable">
<bool>true</bool>
</property>
<property name="currentText">
<string>129.0.0.1</string>
</property>
</widget>
</item>
</layout>
</item>
@ -62,7 +69,7 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_2">
<widget class="QSpinBox" name="spinBoxPort">
<property name="maximum">
<number>65000</number>
</property>
@ -81,14 +88,14 @@
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="btnUnicast">
<property name="text">
<string>单播发送</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="btnBroadcast">
<property name="text">
<string>广播发送</string>
</property>