QUdp不能很好支持大网络数据包情况

766 阅读1分钟

最近在用QT做应用程序开发,采用UDP通讯模式,部分代码如下:

QUdpSocket     *udpSocket;
udpSocket = new QUdpSocket(this);  

connect(udpSocket, SIGNAL(readyRead()),this, SLOT(readPendingDatagrams())); 


   void UdpClient::readPendingDatagrams()  
   {  
       while (udpSocket->hasPendingDatagrams())   
       {  
           QByteArray datagram;  
           datagram.resize(udpSocket->pendingDatagramSize());  
           QHostAddress sender;  
           quint16 senderPort;  
           udpSocket->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);  
       }  
   }  

该代码在网络数据量不高时比如10kB/s能够正常工作,但是当软件系统网络数据包为30kB/s以及以上时,发现程序运行一段时间后直接报段错误,软件异常时的栈调用如下所示:

通过对对栈提示信息进行分析,发现问题可能出现在socket通讯部分,通过对程序进行走读,发现程序在进行读写操作时都进行了必要的加锁解锁操作。推测可能是因为QUDP本身的问题,即在某些应用场景下QUDP对大带宽的网络通讯不能很好支持。于是我采用C的socket相关模块对QUDP通讯相关模块进行重写,部分代码如下:

//创建socket对象
     int sockfd=socket(AF_INET,SOCK_DGRAM,0);
 
     //创建网络通信对象
     struct sockaddr_in addr;
     addr.sin_family =AF_INET;
     addr.sin_port =htons(1333);
     addr.sin_addr.s_addr=inet_addr("127.0.0.1");
 
     //绑定socket对象与通信链接
     int ret =bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
     if(0>ret)
     {
         printf("bind\n");
         return -1;
 
     }
     struct sockaddr_in cli;
     socklen_t len=sizeof(cli);
 
     while(1)
     {
         char buf =0;
         recvfrom(sockfd,&buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);
     }
     close(sockfd);

完成后对软件进行压力测试,发现在大网络数据包情况下,软件系统能够正常运行。可见采用C的socket会比QUdpSocket健壮性好。