推荐一个不错的人工智能学习网站,通俗易懂,内容全面,作为入门科普和学习提升都不错,分享一下给大家:前言https://www.captainbed.cn/ai
一.UDP通信
1.QT中实现UDP通信主要用到了以下类:QUdpSocket、QHostAddress;
2.UdpServer是服务器端,用于监听客户端发送的消息并回复同样的消息;
UdpClient是客户端,用于向服务器发送一条消息,并等待来自服务器的回复;
3.UDP与TCP的区别
UDP像写信,只要知道地址就可以发
TCP像打电话,只有两人同时在线才能通信
4.UDP多播组播
二.示例代码
本示例代码实现功能为本地管理的组播收发功能。
1.mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QLabel *LabSocketState;
QUdpSocket *udpSocket;//用于与连接的客户端通讯的QTcpSocket
QHostAddress groupAddress;//组播地址
QString getLocalIP();//获取本机IP地址
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
//自定义槽函数
void onSocketStateChange(QAbstractSocket::SocketState socketState);
void onSocketReadyRead();//读取socket传入的数据
void on_actStart_triggered();
void on_actStop_triggered();
void on_actClear_triggered();
void on_actHostInfo_triggered();
void on_btnMulticast_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2.mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
QString MainWindow::getLocalIP()
{
QString hostName=QHostInfo::localHostName();//本地主机名
QHostInfo hostInfo=QHostInfo::fromName(hostName);
QString localIP="";
QList<QHostAddress> addList=hostInfo.addresses();//
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
if (QAbstractSocket::IPv4Protocol==aHost.protocol())
{
localIP=aHost.toString();
break;
}
}
return localIP;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
LabSocketState=new QLabel("Socket状态:");//
LabSocketState->setMinimumWidth(200);
ui->statusBar->addWidget(LabSocketState);
QString localIP=getLocalIP();//本地主机名
this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
udpSocket=new QUdpSocket(this);//用于与连接的客户端通讯的QTcpSocket
udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption,1);
connect(udpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
onSocketStateChange(udpSocket->state());
connect(udpSocket,SIGNAL(readyRead()),
this,SLOT(onSocketReadyRead()));
}
MainWindow::~MainWindow()
{
udpSocket->abort();
delete udpSocket;
delete ui;
}
void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
switch(socketState)
{
case QAbstractSocket::UnconnectedState:
LabSocketState->setText("scoket状态:UnconnectedState");
break;
case QAbstractSocket::HostLookupState:
LabSocketState->setText("scoket状态:HostLookupState");
break;
case QAbstractSocket::ConnectingState:
LabSocketState->setText("scoket状态:ConnectingState");
break;
case QAbstractSocket::ConnectedState:
LabSocketState->setText("scoket状态:ConnectedState");
break;
case QAbstractSocket::BoundState:
LabSocketState->setText("scoket状态:BoundState");
break;
case QAbstractSocket::ClosingState:
LabSocketState->setText("scoket状态:ClosingState");
break;
case QAbstractSocket::ListeningState:
LabSocketState->setText("scoket状态:ListeningState");
}
}
void MainWindow::onSocketReadyRead()
{//读取数据报
while(udpSocket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
QHostAddress peerAddr;
quint16 peerPort;
udpSocket->readDatagram(datagram.data(),datagram.size(),&peerAddr,&peerPort);
QString str=datagram.data();
QString peer="[From "+peerAddr.toString()+":"+QString::number(peerPort)+"] ";
ui->plainTextEdit->appendPlainText(peer+str);
}
}
void MainWindow::on_actStart_triggered()
{//加入组播
QString IP=ui->comboIP->currentText();
groupAddress=QHostAddress(IP);//多播组地址
quint16 groupPort=ui->spinPort->value();//端口
if (udpSocket->bind(QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress))//先绑定端口
{
udpSocket->joinMulticastGroup(groupAddress); //加入多播组
ui->plainTextEdit->appendPlainText("**加入组播成功");
ui->plainTextEdit->appendPlainText("**组播地址IP:"+IP);
ui->plainTextEdit->appendPlainText("**绑定端口:"+QString::number(groupPort));
ui->actStart->setEnabled(false);
ui->actStop->setEnabled(true);
ui->comboIP->setEnabled(false);
}
else
ui->plainTextEdit->appendPlainText("**绑定端口失败");
}
void MainWindow::on_actStop_triggered()
{//退出组播
udpSocket->leaveMulticastGroup(groupAddress);//退出组播
udpSocket->abort(); //解除绑定
ui->actStart->setEnabled(true);
ui->actStop->setEnabled(false);
ui->comboIP->setEnabled(true);
ui->plainTextEdit->appendPlainText("**已退出组播,解除端口绑定");
}
void MainWindow::on_actClear_triggered()
{
ui->plainTextEdit->clear();
}
void MainWindow::on_actHostInfo_triggered()
{
QString hostName=QHostInfo::localHostName();//本地主机名
ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");
QHostInfo hostInfo=QHostInfo::fromName(hostName);
QList<QHostAddress> addList=hostInfo.addresses();//
if (!addList.isEmpty())
for (int i=0;i<addList.count();i++)
{
QHostAddress aHost=addList.at(i);
if (QAbstractSocket::IPv4Protocol==aHost.protocol())
{
QString IP=aHost.toString();
ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());
if (ui->comboIP->findText(IP)<0)
ui->comboIP->addItem(IP);
}
}
}
void MainWindow::on_btnMulticast_clicked()
{//发送组播消息
quint16 groupPort=ui->spinPort->value();
QString msg=ui->editMsg->text();
QByteArray datagram=msg.toUtf8();
udpSocket->writeDatagram(datagram,groupAddress,groupPort);
ui->plainTextEdit->appendPlainText("[multicst] "+msg);
ui->editMsg->clear();
ui->editMsg->setFocus();
}
三.测试结果
- 初始状态
2.组播通讯结果