qt中QUdpSocket的readyRead信号不被触发

       在之前的qt控制台程序udp编程中始终面临着一个问题,就是socket的readRead信号绑定了类中的某个接收函数,但是始终不会被自动触发,只能通过手动进行触发,因为不知道何时会接收到消息,所以手动触发的方法不可取。分析之后,可能由于下面三种问题引起的不能触发:

  1. socket的构造方法不对
  2. main函数启动的顺序不对
  3. 焦点问题

      经过几天的尝试,发现是由第三种情况引起的,因为主线程要担负发送和接受的任务,而发送任务是通过循环实现的,不断地监听控制台的输入,输入一行,发送一行。这样就造成了程序的焦点始终是在发送函数上,就算socket的信号发射,主线程也不会调用相应的接收函数。解决的方法就在于将socket的发送和接收端分开,给发送单独建立一个线程,怎样建立线程见另一篇博文:https://blog.csdn.net/mujiangyao/article/details/80917039

      下面代码是通过一个小的聊天程序说明原理。

//client1的主函数
#include <QtCore/QCoreApplication>
#include<client1.h>
#include<windows.h>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	client1 test;
	return a.exec();
}
//client1的函数声明和实现
#pragma once
#include<QObject>
#include<QtNetwork/QUdpSocket>
#include<iostream>
#include<string>
#include<cstring>
#include<windows.h>

using namespace std;

class client1:public QObject
{
	Q_OBJECT
public:
	client1(QObject * parent = NULL);
	static DWORD WINAPI send(void *);
	HANDLE revSend;
	
	~client1();
	QUdpSocket *udpSocket;
	private slots:
	void rev();
	
};

//+++++++++++++++++++++++++++++++实现+++++++++++++++++++++++++++++++++++++++
#include "client1.h"

client1::client1(QObject * parent):QObject(parent)
{
	udpSocket = new QUdpSocket(this);
	udpSocket->bind(port, QUdpSocket::ShareAddress);
	connect(udpSocket, SIGNAL(readyRead()), this, SLOT(rev()));
	CreateThread(NULL, 0, send, (void *)this, 0, NULL);
}


DWORD WINAPI client1::send(void * __this)
{
	client1 * _this = (client1 *)__this;
	while (1)
	{
		QByteArray senddata;
		string commandTmp = "";
		getline(cin, commandTmp);
		senddata.append(commandTmp.data(), commandTmp.size());
		_this->udpSocket->writeDatagram(senddata, QHostAddress(ip), port);
	}
}

void client1::rev()
{
	while (udpSocket->hasPendingDatagrams())
	{
		QByteArray datagram;
		datagram.resize(udpSocket->pendingDatagramSize());
		udpSocket->readDatagram(datagram.data(), datagram.size());
		for (int i = 0; i < datagram.size(); i++)
		{
			printf("%c", datagram.at(i));
		}
		printf("\n");
	}
}

client1::~client1()
{
	delete(udpSocket);
}

        client2的代码与client1的相似,ip和port可以自己自由设置,可以实现通信即可。

  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: QUdpSocket 可以通过将音频文件转换为 QByteArray 类型,然后使用 QUdpSocket 的 writeDatagram() 函数将数据包发送到目标地址和端口。接收方可以使用 QUdpSocketreadDatagram() 函数接收数据包并将其转换回音频文件。 ### 回答2: QUdpSocketQt框架用于进行UDP通信的类,它可以用于传输音频文件。下面是使用QUdpSocket传输音频文件的基本步骤: 1. 创建QUdpSocket对象:在需要传输音频文件的程序,首先需要创建一个QUdpSocket对象,用于进行UDP通信。 2. 打开和绑定UDP端口:使用QUdpSocket的bind()方法来打开和绑定一个UDP端口,以便接收和发送数据。 3. 加载音频文件:使用Qt的文件IO操作,从本地硬盘上加载音频文件到内存。可以使用QFile类打开音频文件,并使用readAll()方法将文件内容读取到一个QByteArray。 4. 将音频文件数据发送出去:使用QUdpSocket的writeDatagram()方法将音频文件数据发送到指定的目标IP和端口号。可以使用QByteArray的constData()方法将数据转换为const char*类型。 5. 接收音频文件数据:使用QUdpSocketreadyRead()信号readDatagram()方法接收来自发送方的音频数据。可以定义一个函数来处理接收到的音频文件数据。 6. 保存音频文件:接收到音频文件数据后,可以使用Qt的文件IO操作,将接收到的数据保存为一个音频文件。可以使用QFile类打开一个文件,并使用write()方法将接收到的数据写入文件。 总结:通过QUdpSocket类的send()和receive()方法,在UDP数据报传输音频文件是可行的。发送方将音频文件读入QByteArray类型,然后使用send()方法将其发送出去。接收方通过receive()方法接收音频文件数据,然后将其写入新打开的文件。这样,就可以实现通过QUdpSocket传输音频文件的功能。 ### 回答3: QUdpSocketQt用于UDP协议通信的类,它提供了与网络上其他设备进行数据传输的功能。 要利用QUdpSocket传输音频文件,我们可以先将音频文件读入内存,并将其分割成较小的数据包。然后,通过QUdpSocket的writeDatagram函数将这些数据包发送到目标设备的指定端口。 接收端的设备需要创建一个QUdpSocket对象,并通过bind函数绑定到一个本地的IP地址和端口上。在接收到数据报时,可以通过QUdpSocketreadyRead信号触发相应的函数进行处理。 在发送时,需要指定目标设备的IP地址和端口,可以通过QUdpSocket的writeDatagram函数的参数来实现。在接收时,可以通过QUdpSocket的读取函数来获取数据报的内容。 音频文件的传输基本上是以流的形式进行的,所以发送端和接收端都应该采用流式数据传输的方式进行。 可以按照如下的步骤来使用QUdpSocket进行音频文件的传输: 1. 创建一个QUdpSocket对象,并通过bind函数绑定到一个本地的IP地址和端口上。 2. 打开要传输的音频文件,并将其读入内存。 3. 将读取到的音频数据分割成较小的数据包,并利用QUdpSocket的writeDatagram函数逐个发送这些数据包。 4. 在接收端,监听QUdpSocketreadyRead信号,并在函数读取接收到的音频数据。 5. 对接收到的音频数据进行一些必要的处理,比如保存到文件或直接播放。 需要注意的是,UDP协议是不可靠的,所以在传输大型音频文件时可能会存在丢包或乱序的问题。为了保证数据的完整性,可以在传输的数据包添加一些校验码、序号等信息,以便在接收端进行验证和重组。同时,也可以使用分片和重传等机制来增加数据的可靠性。 总而言之,利用QUdpSocket传输音频文件主要是将音频数据分割为较小的数据包,并通过QUdpSocket进行传输和接收。但需要注意UDP协议本身的不可靠性以及数据包的分片、重传等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值