Python TCP打孔(旁路监听插座)
我已经有几天没有在打孔了,为了有可靠的行为,但我现在已经走到了死胡同 UDP打孔非常有效:只需先向远程发送数据包,然后让远程发送数据包,因为它将通过源NAT到达。从我的尝试来看,它相当可靠 但是现在是TCP。。。我不明白 现在,我可以通过NAT建立连接,但是只能通过连接插座建立连接:Python TCP打孔(旁路监听插座),python,sockets,tcp,udp,hole-punching,Python,Sockets,Tcp,Udp,Hole Punching,我已经有几天没有在打孔了,为了有可靠的行为,但我现在已经走到了死胡同 UDP打孔非常有效:只需先向远程发送数据包,然后让远程发送数据包,因为它将通过源NAT到达。从我的尝试来看,它相当可靠 但是现在是TCP。。。我不明白 现在,我可以通过NAT建立连接,但是只能通过连接插座建立连接: A.connect(B)->在B的NAT上崩溃,但在A的NAT上打开一个洞。 连接(A)->进入A的NAT孔,到达A的连接插座。 但现在,发送SYN数据包进行连接的两个套接字已连接 你会认为我会这么做,通过2个N
A.connect(B)->在B的NAT上崩溃,但在A的NAT上打开一个洞。
连接(A)->进入A的NAT孔,到达A的连接插座。
但现在,发送SYN数据包进行连接的两个套接字已连接
你会认为我会这么做,通过2个NAT获得连接,万岁
但问题是,这不是一种正常的行为,鉴于本文:,我应该能够有一个与连接套接字并行的侦听套接字
所以我绑定了一个监听套接字,它接受入站连接
但是入站连接总是被连接套接字捕获,而不是被侦听套接字捕获…
e、 g:
#/usr/bin/env蟒蛇3
从套接字导入*
从线程导入线程
插座
#使用的端点:
本地='0.0.0.0',7000
远程='REMOTE',7000
#创建侦听套接字,将其绑定并使其侦听:
侦听=套接字(AF_INET、SOCK_STREAM)
Listening.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
正在侦听。绑定(本地)
听,听(5)
#只需在另一个线程中启动某种调试:
#打印任何连接客户端的地址:
def handle():
不在收听时。\u关闭:
client,addr=Listening.accept()
打印('已接受',地址)
线程(目标=句柄).start()
#现在创建连接套接字:
连接=插座(AF_INET,SOCK_STREAM)
Connecting.setsockopt(SOL_插座,SO_REUSEADDR,1)
连接.绑定(本地)
#现在我们可以尝试连接:
尝试:
连接。连接(远程)
打印('CONNECTED',Connecting.getpeername())
例外情况除外,如e:
打印('trued',键入(e),e)
现在使用此脚本,只需与朋友或其他人商定一个端口,并在一端执行它,Connecting.connect(…)
应该运行一段时间(等待超时,因为SYN数据包撞到了远处的NAT,但幸运的是在自己的NAT上打开了一个洞),同时在另一端执行脚本,现在,Connecting.connect(…)
将返回,因为它已连接
最奇怪的是:监听
套接字从未触发过
为什么??如何让侦听套接字通过连接套接字捕获入站连接
注意:关闭连接插座确实会在网络上发送一些信息,这些信息会立即关闭该孔,至少在我的网络上是这样
第二个注意:我在windows上
编辑:主要问题是,在任何情况下,此脚本都会输出连接[…]的
我想答案就在这里。TCP连接由四个元素组成的元组定义:
- 本地地址
- 本地港口
- 远程地址
- 远程端口
当您建立TCP连接时,您将创建从此元组到本地主机上的连接套接字的绑定
通过NAT发送SYN时,会创建绑定:
-本地地址/端口->公共地址/端口
当远程端将其SYN发送到公共地址/端口时,该地址将被转换为本地地址/端口并发送到本地计算机。在此计算机上,此连接与初始连接无法区分,并且已成功建立(使用SYN/ACK)
这意味着本地端没有接收到初始SYN
如何让侦听套接字通过连接套接字捕获入站连接?
使用源NAT是不可能的。要接受NAT背后的新连接,您需要目标NAT将一些公共IP/端口映射到您的私有IP/端口因此,在进行了更多测试和阅读后,我得出以下结论:
事实上,可以将侦听套接字和在同一地址(ip、端口)上进行出站连接的套接字绑定在一起
但套接字的行为严重依赖于系统/TCP堆栈的实现,如§4.3所述:
客户端应用程序在TCP打孔过程中观察到的套接字情况取决于所涉及的时间和TCP实现。假设A到B的公共端点的第一个出站SYN数据包被NATB丢弃,但是B到A的公共端点的第一个后续SYN数据包在A的TCP重新传输其SYN之前到达A。根据所涉及的操作系统,可能会发生以下两种情况之一:
- A的TCP实现注意到传入SYN的会话终结点与出站会话的会话终结点匹配A正在尝试启动<因此,strong>A
的TCP堆栈将此新会话与A上的本地应用程序用于连接()到B的公共端点的套接字相关联。应用程序的异步connect()调用成功,应用程序的侦听套接字不会发生任何变化。由于接收到的SYN数据包不包括A先前出站SYN的ACK,A的TCP使用SYN-ACK数据包回复B的公共端点,SYN部分仅仅是A原始出站SYN的重播,使用相同的se