求解qt udp接收丢数据问题

lishi_1991 2016-07-22 01:13:30
想用qt编写一个udp接收文件的程序,结果发现udp接收丢包非常严重,不知道大家有没有遇到过的,求助一下
发送端会没有sleep的发送多个1024字节的数据包过来,接收端使用qt QUDPSocket 编程,接收到的数据长度和发送端发送的数据差别很大,丢包率非常大。
而同样的环境下使用vs编写的udp接收程序就没这个问题,发送端和接收端数据长度完全吻合,下面我贴上我qt编写的udp接收程序
 receiver = new QUdpSocket(this);
connect(receiver, SIGNAL(readyRead()), this, SLOT(dataReceived()),Qt::AutoConnection);

port = 12345;
if (!receiver->bind(port, QUdpSocket::ShareAddress)) {
QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
return;
}

static unsigned long recvCount = 0;
void Receiver::dataReceived()
{
// 拥有等待的数据报
while(receiver->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(receiver->pendingDatagramSize());
receiver->readDatagram(datagram.data(), datagram.size());
recvCount += datagram.size();
qDebug()<<"====== "<<recvCount;
//reveiveData->append(datagram);
}
}


然后我又尝试用qt使用windows api编写udp接收程序,发现同样的代码,vs编写下的win32控制台程序就正常,qt 编写的丢包率就非常严重
贴上我用vs 和 qt 调用windows api 编写的udp接收程序
VS2008:

int _tmain(int argc, _TCHAR* argv[])
{
int mSock = createSocket(UDP_SOCK);
struct sockaddr_in fromAddr;
int fromLen = sizeof(fromAddr);
char recvBuf[2048]={0};
unsigned long mCount = 0;
bindSocket(mSock,12345);
while(1){
int recvLen = recvfrom(mSock,recvBuf,sizeof(recvBuf), 0,(struct sockaddr *)&fromAddr, &fromLen);
if(recvLen <= 0){
//QThread::usleep(1000);
continue;
}
mCount += recvLen;
printf(" ==== %d\n",mCount);
}

return 0;
}


QT :

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{

ui->setupUi(this);
createThread();
}

Widget::~Widget()
{
QThread::msleep(1000);
delete ui;
}

void udpRecvThread()
{
int mSock = createSocket(UDP_SOCK);
struct sockaddr_in fromAddr;
int fromLen = sizeof(fromAddr);
char recvBuf[2048]={0};
unsigned long mCount = 0;
bindSocket(mSock,12345);
while(1){
int recvLen = recvfrom(mSock,recvBuf,sizeof(recvBuf), 0,(struct sockaddr *)&fromAddr, &fromLen);
if(recvLen <= 0){
continue;
}
mCount += recvLen;
qDebug()<<"***"<<mCount;
}
}

void Widget::createThread()
{
DWORD stateThreadID = 0;
HANDLE udpThreadHandle= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)udpRecvThread,NULL,0,&stateThreadID);
if(udpThreadHandle==NULL){
printf("create state send speed thread ERR\n");
}
}


现在非常困惑,因为必须使用qt 来编写udp接收程序,如果丢包问题不解决后面都没法做,所以想问大家有没有解决方法 谢谢!
...全文
1122 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Little柯南 2016-07-28
  • 打赏
  • 举报
回复
引用 7 楼 lishi_1991 的回复:
[quote=引用 6 楼 u010111033 的回复:] 个人这么建议,发送信息按照每小段封装进一个结构体里,然后按照socket->write(char*,size)方式发送,按照socket->read(char*,size)方式读取,发送时候取你的结构体地址做char*,size就是sizeof(你的结构体);接收时候先声明一个char* msg = new char【size】,size就是你以前发送的size,读到后memcpy到你的重新定义的结构体里,把他debug出来;我做过很多此类项目,使用这种方式没有出现过你的问题,再多说一句,数据多了,readAll()函数慎用!不然数据不完整你真不好找错误
谢了后面我改成 windows下用winsocket 编程,linux下用linux socket编程[/quote] 这样也行,但是就没有移植性了!
lishi_1991 2016-07-27
  • 打赏
  • 举报
回复
引用 6 楼 u010111033 的回复:
个人这么建议,发送信息按照每小段封装进一个结构体里,然后按照socket->write(char*,size)方式发送,按照socket->read(char*,size)方式读取,发送时候取你的结构体地址做char*,size就是sizeof(你的结构体);接收时候先声明一个char* msg = new char【size】,size就是你以前发送的size,读到后memcpy到你的重新定义的结构体里,把他debug出来;我做过很多此类项目,使用这种方式没有出现过你的问题,再多说一句,数据多了,readAll()函数慎用!不然数据不完整你真不好找错误
谢了后面我改成 windows下用winsocket 编程,linux下用linux socket编程
Little柯南 2016-07-26
  • 打赏
  • 举报
回复
个人这么建议,发送信息按照每小段封装进一个结构体里,然后按照socket->write(char*,size)方式发送,按照socket->read(char*,size)方式读取,发送时候取你的结构体地址做char*,size就是sizeof(你的结构体);接收时候先声明一个char* msg = new char【size】,size就是你以前发送的size,读到后memcpy到你的重新定义的结构体里,把他debug出来;我做过很多此类项目,使用这种方式没有出现过你的问题,再多说一句,数据多了,readAll()函数慎用!不然数据不完整你真不好找错误
dext 2016-07-24
  • 打赏
  • 举报
回复
首先要明白 丢包 是代码问题,还是 协议问题。代码问题改代码,协议问题 就用UDP实现 TCP. Qt 尽量保证 代码在 各种平台和 编译器下行为一样,但是不是绝对。Qt 网络这块 写代码非常注意。 Qt Network 这块代码 很难发现 bug,因为构建在其上的代码,太多了。
FlyToTMoon 2016-07-22
  • 打赏
  • 举报
回复
qt上网络之前用的zmq。。很好用,完全没用过QT自带的
lishi_1991 2016-07-22
  • 打赏
  • 举报
回复
没有人遇到过吗
lishi_1991 2016-07-22
  • 打赏
  • 举报
回复
图片传错了,vs 控制程序测试结果如下:
lishi_1991 2016-07-22
  • 打赏
  • 举报
回复
补充两个测试结果截图
VS 控制台程序测试结果:


qt测试结果

16,175

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧