QT版本:Qt 5.5.1 (MSVC 2013, 32 bit)
Qt Creator版本:Qt Creator 3.5.1 (opensource)
系统:win10
1号坑:
关于使用QUdpSocket来接收包的操作遇到了如下问题:
如果在MainWindow的构造函数中编写如下代码,
m_SocketCommandBack = new QUdpSocket();//testudp
m_SocketCommandBack->bind(QHostAddress("192.168.5.23"),10086);
QObject::connect(m_SocketCommandBack,SIGNAL(readyRead()),this,SLOT(RecvCommandBack()));
//m_SocketCommandBack是QUdpSocket实例化的对象,
//RecvCommandBack()是在MainWindow类中定义的槽函数
则程序能接收到别人发过来的包,并响应RecvCommandBack()函数,
但如果是在自己创建的类A中使用上述用法,则m_SocketCommandBack不会触发该类的RecvCommandBack(),即使类A继承于QObject类!
所以解决方法如下:
不要用connect来处理接收包,而是直接在程序中用m_SocketCommandBack->waitForReadyRead(1000)来等待是否接收到回包,代码如下:
m_SocketCommand->writeDatagram(baData,m_strRemoteIP,m_nCommandPort);
if(m_SocketCommandBack->waitForReadyRead(2000))//判断是否在2s内m_SocketCommandBack接收到包
{
QByteArray baRecv;
while(m_SocketCommandBack->hasPendingDatagrams())//socket中有数据
{
baRecv.resize(m_SocketCommandBack->pendingDatagramSize());
m_SocketCommandBack->readDatagram(baRecv.data(),baRecv.size());
}
}
2号坑:
用qt编写的同样的代码,发送udp包,如下:
m_SocketSendCSV->writeDatagram(baData,QHostAddress(192.168.5.10),10086);
如果是在windows电脑下发送10000包数据包,丢包率接近7%!
如果是在linux电脑下发送10000包数据包,丢包率接近0%!
3号坑:
用writeDatagram方法发送数据时候,一包的大小不要超过8192字节!
理论上来说一个UDP包的内容只要不超过65535字节就行,但实际上,用qt封装的类去发送字节的时候,如果超过8192字节,则丢包会很严重!(其实官方文档中关于方法writeDatagram的说明是,建议一包数据不要超过512字节,不过我实际测试的时候发现问题不大,只要不超过8192字节就几乎不丢包)
如果你坚持要发送一包超过8192字节数据,我建议你用windows或linux下系统自带的socket通信API,不要用qt封装过的方法。