概述
1目标地址和目标端口都是自己写的,绑定端口也是自己写的
2udp是无连接传输,每个客户机都有一个自己的socket
3.每一个客户机的socket中在开始连接之前都要写本机的信息(本机IP,端口,想要的目标机的ip和端口等)和想要发的内容
4.当每个客户机都完善自己的socket后,每个客户机的socket都自动在网络中寻找对应的socket,并见面后自动更新数据把对方的信息放在自己里面
5.这样一来只要socket里的信息增加了就可以去读取里面的对方的内容
步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 1.头文件 include <QMainWindow> include<QLabel> include<QUdpSocket> 1 定义udp的socket QUdpSocket *udpSocket; 2 实现槽函数 private slots:
void onSocketStateChange(QAbstractSocket::SocketState socketState); void onSocketReadyRead();
void on_actStart_triggered(); void on_actStop_triggered(); void on_btnSend_clicked(); void on_action_3_triggered(); void on_btnBroadcast_clicked();
|
函数实现过程
一 完善socket信息
1.绑定端口void on_actStart_triggered();
2.向socket写入目标ip,目标端口和发送内容void on_btnSend_clicked();
主要是socket里的writeDatagram写入(eg: //socket里放入目标ip目标端口和发送的消息
udpSocket->writeDatagram(str,targetAddr,targetPort);)
二读取收到的数据 void onSocketReadyRead();
若socket有新数据返回,则自动产生readyRead()信号
若socket有新数据则socket里的hasPendingDatagrams()会返回1
通过socket里的readDatagram()函数可以读取对对方的信息(包括IP,端口)
三 解除端口绑定不再连接void on_actStop_triggered();
socket里有abort()函数可以消灭连接
四若实现广播,第二步在写socket时writeDatagram(发送内容,QHostAddress::Broadcast,目标端口);//指明了方式Broadcast,所以没写目标IP
函数代码
获取本机ip
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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; }
|
构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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); ui->comboTargetIP->addItem(localIp); udpSocket=new QUdpSocket(this); connect(udpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState))); connect(udpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}
|
读取socket传入的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 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="来自"+peerAddr.toString()+"的"+QString::number(peerPort)+"端口:"; ui->plainTextEdit->appendPlainText(peer); ui->plainTextEdit->appendPlainText(str);
}
}
|
点击绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void MainWindow::on_actStart_triggered() { quint16 port=ui->spinBindPort->value(); if(udpSocket->bind(port)) { ui->plainTextEdit->appendPlainText("**已成功绑定"); ui->plainTextEdit->appendPlainText("**绑定端口:"+QString::number(udpSocket->localPort())); ui->actStart->setEnabled(false); ui->actStop->setEnabled(true); } else{ ui->plainTextEdit->appendPlainText("**绑定失败"); } }
|
点击解绑
1 2 3 4 5 6 7
| void MainWindow::on_actStop_triggered() { udpSocket->abort(); ui->actStart->setEnabled(true); ui->actStop->setEnabled(false); ui->plainTextEdit->appendPlainText("**已经解除绑定"); }
|
点击发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void MainWindow::on_btnSend_clicked() { QString targetIp=ui->comboTargetIP->currentText(); QHostAddress targetAddr(targetIp); quint16 targetPort=ui->spinTargetPort->value(); QString msg=ui->editMsg->text(); QByteArray str=msg.toUtf8(); udpSocket->writeDatagram(str,targetAddr,targetPort); ui->plainTextEdit->appendPlainText("[out]"+msg); ui->editMsg->clear(); ui->editMsg->setFocus(); }
|
点击广播
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void MainWindow::on_btnBroadcast_clicked() { quint16 targetPort=ui->spinTargetPort->value(); QString msg=ui->editMsg->text(); QByteArray str=msg.toUtf8(); udpSocket->writeDatagram(str,QHostAddress::Broadcast,targetPort); ui->plainTextEdit->appendPlainText("本机已发布广播:"+msg); ui->editMsg->clear(); ui->editMsg->setFocus(); }
|
点击清空文本
1 2 3 4
| void MainWindow::on_action_3_triggered() { ui->plainTextEdit->clear(); }
|
源码:链接:https://pan.baidu.com/s/1Pl-YGquor1JMVlOHI57dog?pwd=waat
提取码:waat