- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
为了获得某种可靠的行为,我已经有几天没玩过打洞了,但我现在陷入了死胡同。
UDP 打洞效果很好:只需先向远程发送一个数据包,然后让远程发送一个数据包,因为它将通过源 NAT 到达。根据我的尝试,它相当可靠。。
但是现在出现了 TCP...我不明白。
现在,我可以通过 NAT 建立连接,但只能使用连接套接字:
A.connect(B) -> Crash agains't B's NAT, but open a hole in A's NAT.
B.connect(A) -> Get in A's NAT hole, reach A's connecting socket.
但是现在,发送SYN数据包进行连接的两个套接字已经连接了。
你会认为我会做到这一点,通过 2 个 NAT 建立连接,万岁。
但问题是这不是正常行为,并给出了本文:http://www.brynosaurus.com/pub/net/p2pnat/ ,我应该能够有一个与连接 socket 并联的监听 socket 。
所以我确实绑定(bind)了一个监听套接字,它将接受入站连接。
但是入站连接总是被连接套接字捕获,而不是被监听套接字捕获...</strong>
例如:
#!/usr/bin/env python3
from socket import *
from threading import Thread
Socket = socket
# The used endpoints:
LOCAL = '0.0.0.0', 7000
REMOTE = 'remote', 7000
# Create the listening socket, bind it and make it listen:
Listening = Socket(AF_INET, SOCK_STREAM)
Listening.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
Listening.bind(LOCAL)
Listening.listen(5)
# Just start in another thread some kind of debug:
# Print the addr of any connecting client:
def handle():
while not Listening._closed:
client, addr = Listening.accept()
print('ACCEPTED', addr)
Thread(target=handle).start()
# Now creating the connecting socket:
Connecting = Socket(AF_INET, SOCK_STREAM)
Connecting.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
Connecting.bind(LOCAL)
# Now we can attempt a connection:
try:
Connecting.connect(REMOTE)
print('CONNECTED', Connecting.getpeername())
except Exception as e:
print('TRIED', type(e), e)
现在有了这个脚本,只需与 friend 或其他人商定一个端口,然后在一端执行它,Connecting.connect(...)
应该运行一会儿(等待超时,因为SYN包撞到远处的NAT,幸好在自己的NAT开了个洞),同时在另一端执行脚本,此时Connecting.connect(...)
会返回因为它将连接。
最奇怪的部分是:Listening
套接字从未被触发。
为什么?如何让监听套接字通过连接套接字捕获入站连接?
注意:关闭连接套接字确实会在网络上发送一些东西,这会立即关闭漏洞,至少在我的网络上是这样。
第二个注意事项:我在 Windows 上。
编辑:主要问题是在任何情况下,此脚本都会输出CONNECTED [...]
而不是CLIENT [...]
,这在一些讲座中是不应该发生的。
最佳答案
所以,经过更多的测试和阅读,这就是我的结论:
事实上,可以在同一个地址(ip、端口)上绑定(bind)一个监听套接字和一个出站连接套接字。
但是套接字的行为在很大程度上取决于系统/TCP 堆栈的实现,如 http://www.brynosaurus.com/pub/net/p2pnat/ 中所述在§4.3:
What the client applications observe to happen with their sockets during TCP hole punching depends on the timing and the TCP implementations involved. Suppose that A's first outbound SYN packet to B's public endpoint is dropped by NAT B, but B's first subsequent SYN packet to A's public endpoint gets through to A before A's TCP retransmits its SYN. Depending on the operating system involved, one of two things may happen:
A's TCP implementation notices that the session endpoints for the incoming SYN match those of an outbound session A was attempting to initiate. A's TCP stack therefore associates this new session with the socket that the local application on A was using to connect() to B's public endpoint. The application's asynchronous connect() call succeeds, and nothing happens with the application's listen socket.
Since the received SYN packet did not include an ACK for A's previous outbound SYN, A's TCP replies to B's public endpoint with a SYN-ACK packet, the SYN part being merely a replay of A's original outbound SYN, using the same sequence number. Once B's TCP receives A's SYN-ACK, it responds with its own ACK for A's SYN, and the TCP session enters the connected state on both ends.Alternatively, A's TCP implementation might instead notice that A has an active listen socket on that port waiting for incoming connection attempts. Since B's SYN looks like an incoming connection attempt, A's TCP creates a new stream socket with which to associate the new TCP session, and hands this new socket to the application via the application's next accept() call on its listen socket. A's TCP then responds to B with a SYN-ACK as above, and TCP connection setup proceeds as usual for client/server-style connections.
Since A's prior outbound connect() attempt to B used a combination of source and destination endpoints that is now in use by another socket, namely the one just returned to the application via accept(), A's asynchronous connect() attempt must fail at some point, typically with an “address in use” error. The application nevertheless has the working peer-to-peer stream socket it needs to communicate with B, so it ignores this failure.The first behavior above appears to be usual for BSD-based operating systems, whereas the second behavior appears more common under Linux and Windows.
其实我属于第一种情况。在我的 Windows 10 上。
这意味着为了为 TCP Hole Punching 做一个可靠的方法,我需要在连接套接字的同时绑定(bind)一个监听套接字,但我稍后需要检测哪个触发(监听或连接)并通过它沿着应用程序的流程向下移动。
关于python - TCP Hole Punching(绕过监听套接字),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44012683/
我想知道是否有任何方法可以逃避 __metatable 元方法。我知道没有,但我正在尝试做这样的事情,但显然 __metatable 阻止了这种情况的发生: -- pretend that t
我想知道如果满足某些条件,是否可以跳过 do while 循环,甚至中途退出方法?这是我的意思的一个例子(一切正常) public void loanBook() { Sc
曾几何时,一位前端开发人员有一些菜单,当有人在页面上的任何位置单击菜单之外时,他想要关闭一些菜单,因此他使用了一些 if 和提到的方法来处理他的工作。当然,后来这又让他痛不欲生,因为在上述菜单中进行的
我开发了一个内核模块,它完成了繁重的工作,当然需要时间。问题是模块使用 CPU 超过 20 秒,并且结果引发了softlockup_threshold的BUG。 我的问题是,有什么办法可以绕过这个吗?
我相信我对避免代码重复这个长期存在的问题提出了一个略有不同的看法。设置相当标准——一堆 if 语句执行类似的操作。下面是一个简短示例。 我正在尝试从代码效率、紧凑性和程序员易用性方面找出解决此类情况的
我的服务器上有 10 秒,这对我想要做的事情来说还不够。它也被网络托管商禁用了。 如果在执行了一定时间后,我执行了一个单独的 PHP 页面,这算在同一时间还是在该页面上重新开始? 还有别的办法吗? 最
我已经下载并编译了 Microsoft 迂回库。在我的项目中,我包含了头文件并添加了 .lib 文件作为依赖项。一切都编译无误。现在我一直在尝试绕过 DrawText,但由于某种原因根本没有调用绕过的
我正在使用 Mockito 编写一个 JUnit 测试用例,我试图绕过我的测试方法中的静态方法调用。运行测试用例时出现 NullPointerException。 是否有任何方法可以在不使用 Powe
我不知道为什么,这很奇怪,但是我的代码在循环。实际上,在第一张表 (ws1) 中,我正在 Worksheet_Change 上执行此操作事件 : Application.EnableEvents =
我正在尝试在 Ubuntu Docker 容器上安装 icinga2-ido-pgsql。 我的数据库在一个单独的容器中。 要安装它,我运行 RUN apt-get install -q -y ici
我在 Dynamics AX 2012 中有一个 AOT 查询,它由 HcmWorker 和 HcmEmployment 表(等等)组成。我的问题是,当我创建报告(不是 SSRS)或以其他方式使用此查
我需要通过cdn将SDK集成到我的next.js项目中所以我需要把 ' />进入我的代码。然后运行 window.sdk = new PrivateSDK()和 window.sdk.someFu
有没有办法可以绕过 Java 中的错误消息? 如果我得到一个错误,但没有可行的方法来改变我的程序怎么办?如果我怀疑我可能会从代码块中得到错误,但我不知道它何时或是否会发生,该怎么办?有很多次我不得不让
我有以下 HTML Facebook 我有一个 onclick 事件处理程序,当单击上面的链接时,会调用 window.open。这在 Chrome 中有效,但在 Safari 中无效。如何让它在 S
我们正在编写一个 ASP.NET MVC 应用程序。默认情况下,如果客户端浏览器具有 Javascript,页面上每个表单的处理程序都会由 Javascript 设置为将提交内容发送到 Ajax“管道
我正在使用 Cloudflare 来加速我的网站,它非常适合。不幸的是,我的一些用户需要将大于 Cloudflare 允许的最大值(即 300MB 大小)的视频上传到我的网站。有什么方法可以告诉 Cl
我正在尝试编写一个自定义中间件,通过检查请求中是否存在 :user key 来检查用户是否经过身份验证。 (defn wrap-authenticated [handler] (fn [{user
你好,祝你有美好的一天。 这里需要一些帮助: 情况: 我有一个不起眼的 DirectX 9 应用程序(名称和应用程序详细信息与问题无关),自某些驱动程序版本以来,它会导致所有 nvidia 卡(GeF
我喜欢制作高效的应用程序,并且经常寻求并发和多线程来提高应用程序响应能力等,但最近我的尝试似乎总是被 WPF 的单线程性所阻碍。无论我的代码多么高效和并行,WPF 似乎都会不断地拖延我的 UI,并使我
我正在使用 Cloudflare 来加速我的网站,它非常适合。不幸的是,我的一些用户需要将大于 Cloudflare 允许的最大值(即 300MB 大小)的视频上传到我的网站。有什么方法可以告诉 Cl
我是一名优秀的程序员,十分优秀!