首页 > 解决方案 > QTCPSocket - 当主机连接到单独的网络时如何强制连接到特定的网络

问题描述

目前我们的工具用于QTCPSocket->ConnectToHost连接到我们的 TCP 服务器,它可以工作。

当我们的某些机器跨两个完全不同的 IP 范围(10.xxx、172.xxx)桥接两个网络时,就会出现问题。当您尝试连接到 172.xxx 网络上的设备时,它似乎正在尝试通过 10.x 网络接口进行连接,然后超时并无法连接。在 Windows 上,如果禁用 10.x 网络的网络端口并重新加载该工具,它会正确使用 172.x 网络接口并连接。我看不到 QTCPSocket 无法强制它使用特定接口进行连接,还是我遗漏了什么?似乎 10.x 网络正在以某种方式获得优先权,我们总是在尝试建立传出连接时尝试使用它,这不是我们想要的。

理想情况下,用户将能够选择他们想要用来建立连接的网络接口,无论是 10.x 还是 172.x 网络。

这是使用 QT 5.15.0。

标签: qtqt5

解决方案


bind()您可以通过首先使用您的接口地址调用来选择要使用的传出接口。这将选择您要使用的传出地址。

请参阅绑定函数的文档

对于 TCP 套接字,此函数可用于指定用于传出连接的接口,这在多个网络接口的情况下很有用。

我为您整理了一个非常简单的演示:

它全部在本地运行。这是服务器 main.cpp:

#include <QCoreApplication>
#include <QTcpServer>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTcpServer serv;

    QObject::connect(&serv, &QTcpServer::newConnection, [](){
       qDebug() << "New connection!";
    });
    qDebug() << serv.listen(QHostAddress("192.168.x.y"), 1337);

    return a.exec();
}

这是客户端 main.cpp:

#include <QCoreApplication>
#include <QDebug>
#include <QTcpSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTcpSocket s;
    qDebug() << s.bind(QHostAddress("127.0.0.1"));
    s.connectToHost(QHostAddress("192.168.x.y"), 1337);


    return a.exec();
}

通过调用bind我们告诉客户端使用本地接口发送数据包,但由于服务器只监听我的 wifi 接口 192.168.xy 连接将失败。如果您现在更改以下行:

qDebug() << s.bind(QHostAddress("127.0.0.1"));

像这样:

qDebug() << s.bind(QHostAddress("192.168.x.y"));

您将看到服务器将接收连接,因为我们明确选择了要发送的接口。

但是,操作系统应该为您选择正确的接口(在演示中意味着:通过不调用 bind 您应该获得连接)。如果没有发生这种情况,您将遇到不同的问题。

要获取您可以使用的所有可用接口的列表,QNetworkInterface::allInterfaces()这将授予您访问您可能需要知道的所有内容的权限。


推荐阅读