我必须通过UDP与一些设备通信。问题是,如果没有bind()的特殊情况,QUdpSocket根本不能工作。我使用connectToHost()方法for access to read()/write() functions。
使用代码时,UDP交换完全不起作用:
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);
m_udp.waitForConnected();I没有收到任何字节。Wireshark中的消息:

下面的代码也不起作用:
m_udp.bind(QHostAddress("192.168.100.15"), 4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);
m_udp.waitForConnected();只有这段代码可以工作:
m_udp.bind(4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);
m_udp.waitForConnected();但是代码只能在Qt 5.6.2中运行,不能在Qt 5.4.2中运行。以下是我尝试接收的方式:
dev->waitForReadyRead(500);
QByteArray ba = dev->readAll();为什么这种行为如此奇怪?如何理解这一点呢?
发布于 2017-09-14 00:00:24
您还没有显示另一端的代码,但显然从所示的wireshark图像可以看出,远程对等项期望您的套接字绑定到端口4001。
第一个代码片段试图连接到(RemoteAddress,4001),但没有指定本地端口(因此内核分配了一个任意端口号(根据wireshark,64875),但如上所述,另一端希望发送回端口4001。因此,您不能在端口64875上接收它。
在UDP中,没有真正的连接。当您使用connectToHost时,实际上只是指定了远程端的IP地址和端口号。确保远程端发送回正确的端口是应用程序的责任。这可以通过以下方式来完成:(a)总是发送到特定端口(如这里显然正在进行的),或者(b)另一侧可以查看从其实际接收到数据报的地址/端口,并将其发送回该端口;换句话说,远程侧可以确定其接收到的数据报是从端口64875发送的,并且将其回复定向到该端口。
在第二次尝试中,您试图将本地端点绑定到另一台计算机上的地址,这是没有任何意义的。(我猜测,如果将绑定更改为m_udp.bind(QHostAddress("192.168.100.3"), 4001); --本地计算机的IP地址,则此代码段可以正常工作。)
只有第三个代码片段有效,因为在这里,您绑定到本地端口4001而没有指定IP地址,然后还发送到远程机器上的端口4001。如果您仅在bind中指定端口号,则IP地址将保留为“通配符”,因此您应该将数据包发送到计算机的任何IP地址上的该端口号。
(不知道为什么您会在早期版本的Qt中看到不同的行为。)
发布于 2017-09-19 22:59:03
在写入或读取之前,检查绑定后套接字的状态。
请参阅以下代码:
QHostAddress serverIP("172.168.1.100");
if(socket->bind(serverIP,port,QUdpSocket::ShareAddress)) //even if local Host dont have static IP( on subnet expected 172.168.x.x),still it becomes true and enters if.
{
if( (socket->state() == QAbstractSocket::BoundState) && (((socket->localAddress()).protocol()) == QAbstractSocket::IPv4Protocol) ) //ignore protocol validation if not required.
{
}
else
{
qDebug()<<"Socket not in bound state. address is: "<<QHostAddress::LocalHost<<" and the port "<<port;
//Return = false;
}
}
else
{
qDebug()<<"Failed to bind socket to the address "<<QHostAddress::LocalHost<<" and the port "<<port;
//Return = false;
}其次,Qt中的套接字会在出现错误时发出错误信号。因此,您应该有一个插槽来捕获这些错误信号。这样你就可以知道问题背后的原因了。
例如:
connect(udpsocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError)));接收套接字错误的插槽:
void SomeInterface::onSocketError(QAbstractSocket::SocketError socketError)
{
qDebug()<<"socket error occured and the error is : "<<socketError;
}https://stackoverflow.com/questions/46198546
复制相似问题