首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果没有绑定,QUdpSocket将无法工作

如果没有绑定,QUdpSocket将无法工作
EN

Stack Overflow用户
提问于 2017-09-13 21:11:48
回答 2查看 2.2K关注 0票数 1

我必须通过UDP与一些设备通信。问题是,如果没有bind()的特殊情况,QUdpSocket根本不能工作。我使用connectToHost()方法for access to read()/write() functions

使用代码时,UDP交换完全不起作用:

代码语言:javascript
复制
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

I没有收到任何字节。Wireshark中的消息:

下面的代码也不起作用:

代码语言:javascript
复制
m_udp.bind(QHostAddress("192.168.100.15"), 4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

只有这段代码可以工作:

代码语言:javascript
复制
m_udp.bind(4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

但是代码只能在Qt 5.6.2中运行,不能在Qt 5.4.2中运行。以下是我尝试接收的方式:

代码语言:javascript
复制
dev->waitForReadyRead(500);
QByteArray ba = dev->readAll();

为什么这种行为如此奇怪?如何理解这一点呢?

EN

回答 2

Stack Overflow用户

发布于 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中看到不同的行为。)

票数 3
EN

Stack Overflow用户

发布于 2017-09-19 22:59:03

在写入或读取之前,检查绑定后套接字的状态。

请参阅以下代码:

代码语言:javascript
复制
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中的套接字会在出现错误时发出错误信号。因此,您应该有一个插槽来捕获这些错误信号。这样你就可以知道问题背后的原因了。

例如:

代码语言:javascript
复制
connect(udpsocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError)));

接收套接字错误的插槽:

代码语言:javascript
复制
void SomeInterface::onSocketError(QAbstractSocket::SocketError socketError)
{
    qDebug()<<"socket error occured and the error is : "<<socketError;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46198546

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档