RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1546438
Accepted
D .Stark
D .Stark
Asked:2023-10-18 00:39:18 +0000 UTC2023-10-18 00:39:18 +0000 UTC 2023-10-18 00:39:18 +0000 UTC

TCP打洞无法建立连接

  • 772

我正在实现一种算法,用于使用 TCP 打孔技术在两个客户端之间创建直接连接,该连接可能位于 NAT 后面。我在C++中使用WinSock2接口。

通过服务器交换外部地址后,客户端关闭连接(shutdown使用SD_BOTH和标志调用closesocket)并尝试直接创建新连接(套接字绑定到以前使用的端口)。接下来,发生数据交换。

如果成功,TCP 数据包日志如下所示:

米。 1

我在家庭网络上进行测试,两个客户端都在同一台计算机上运行。我认为,为了正确实施,应该没有区别。

192.168.153.196:52023 - 客户端 1、192.168.153.196 : 51722 - 客户端 2。在屏幕截图中,您可以看到客户端 1 发送的 SYN 段已成功传递到客户端 2,随后是 ACK 段,并开始通过路由器进行数据交换。在这种情况下,我们有一种 NAT,其中内部端口 = 外部端口(即,例如客户端 1 也从端口 52023 访问公共网络)。

当客户端无法相互建立连接时,请考虑以下日志:

米。 2

192.168.1.106:52478 - 客户端 1、192.168.1.106 : 52477 - 客户端 2。接下来,日志中会重复发送一系列 SYN 段,直到客户端确信无法建立连接。显然,本例中未创建 NAT 映射。这里有一种不同类型的 NAT - 内部端口与外部端口不对应;客户端也运行在同一台机器上。

这是另一个不成功的示例,但已经在第一个示例的网络上(192.168.153.196:51640 - 客户端 1、192.168.153.196: 51639 - 客户端 2):

在此输入图像描述

在这种情况下,据我了解,由于某种原因路由器重置了连接。

问题是,我做错了什么?每个客户端都知道另一个客户端的正确外部地址,在关闭与服务器的连接后短暂超时后,在大约相同的时间点,它们尝试从旧端口(调用)相互创建连接,但是路由器重置连接或不创建 NAT 条目connect。


还有另一个奇怪的时刻。建立连接后,从交换开始最多几分钟,会出现以下情况:

在此输入图像描述

随后几次尝试重新发送均不成功 - 数据包似乎被路由器忽略并且未转发。在这种情况下,调用send不会显示错误,而recv只是在接收方被阻止,因为它看不到数据。

c++
  • 1 1 个回答
  • 109 Views

1 个回答

  • Voted
  1. Best Answer
    user5926
    2023-10-26T20:21:07Z2023-10-26T20:21:07Z

    此方法不适用于所有 NAT 类型,因为它们的行为未标准化。当两台主机通过传出连接相互连接时,处于同时打开TCP连接的状态,必须满足以下条件:

    为了使 TCP 同时打开工作,NAT 应该:

    • 不发送 RST 作为对不属于任何数据包一部分的传入 SYN 数据包的响应
    • 当 NAT 先前发现同一端点的传出 SYN 时,映射接受公共端点的传入 SYN

    这足以保证 NAT 在 TCP 同时打开方面表现良好。

    • 1

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5