qt - 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。
解决方案
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()
这将授予您访问您可能需要知道的所有内容的权限。
推荐阅读
- c++ - 在 C++ 中,Greater_equal
有一种功能 - git - Git checkout 早先提交,进行更改,使其成为新主人
- r - R - 将数据框列中的所有元素与另一个数据框中的行中的元素进行比较,跨越所有列
- php - 需要 WordPress 短代码在 div 而不是 ul 中发布
- flutter - 以编程方式改变方向
- r - 我正在尝试在 Shinyapp 中绘图,但出现反应性错误
- python - 为什么 python 中的 hash() 函数需要恒定的时间来操作可变长度的字符串?
- c# - C# SRI 哈希生成器
- vue.js - 输入字段的绑定值在 Vue 中不会更新
- laravel - Laravel Yajra 数据表原始 SQL