最近在用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健壮性好。