UDP打洞實驗

2022-09-17 07:00:13 字數 2975 閱讀 7687

依雲posted @ 2 年前 in 網路 with tags python

網路socat

udp , 7095 閱讀

兩台沒有外網 ip、在 nat 後邊的主機如何直連?udp打洞通常可行,但是需要第三方伺服器。方法如下:

在伺服器 s 上監聽乙個 udp 埠,在收到 udp 資料報後把源位址發回去。**如下(github):

udpaddr12

3456

78910

1112

1314

1516

1718

1920

21importsys

importtime

importsocket

defmain(port):

s=socket.socket(socket.af_inet, socket.sock_dgram)

s.bind(('', port))

try:

whiletrue:

data, addr=s.recvfrom(4096)

back='your address is %r\n'%(addr,)

s.sendto(back.encode(), addr)

print(time.strftime('%y-%m-%d %h:%m:%s'), addr,'just sent us a message:', data.decode('utf-8','replace'), end='')

exceptkeyboardinterrupt:

print()

if__name__=='__main__':

try:

main(int(sys.ar**[1]))

except(valueerror, indexerror):

sys.exit('which port to listen?')

主機 a 傳送資料報:12

3$ socat readline udp:xmpp.vim-cn.com:2727,sourceport=4567

my addr?

your address is ('a.b.c.d', 40060)

輸入任意訊息並回車,乙個 udp 就從本地的 4567 傳送出去了。從上述示例我們可以看到,nat 裝置**時是從 40060 埠傳送出去的。為了讓伺服器返回的資料能夠到達內網主機,在一段時間內,nat 裝置會記住外網來自 40060 埠的 udp 資料報要傳送給主機 a.b.c.d 的 4567 埠。完全圓錐型nat不會在意外部資料報是從什麼地方發回來的。受限圓錐型nat會忽略掉其它主機的資料報,上例中只認可來自 xmpp.vim-cn.com 的資料報。埠受限圓錐型nat更進一步地要求源埠(上例中是 2727)必須跟之前發出的資料報的目的埠一致。當然,「之前發出的資料報」不必是最後乙個。所以,除了最後一種——對稱nat——之外,其它型別的nat都是有可能成功穿透的。參見維基百科條目網路位址轉換和stun。

後來通過 pystun 程式,我得知我所處的 nat 是完全圓錐型的。12

34# host a

$ socat readline udp-listen:4567

# host b

$ socat readline udp:a:4567

然後 b 先傳送資料讓 a 知道 b 的位址(socat 會 connect 到這個位址),雙方就可以相互通訊了。當然,因為是 udp 協議,所以通訊是不可靠的,丟包啊亂序啊都有可能。

2023年10月13日更新:想要連線到 nat 後邊的 mosh 請看這裡~

UDP打洞實驗

兩台沒有外網 ip 在 nat 後邊的主機如何直連?udp打洞通常可行,但是需要第三方伺服器。方法如下 在伺服器 s 上監聽乙個 udp 埠,在收到 udp 資料報後把源位址發回去。如下 github udpaddr 12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

TCP打洞和UDP打洞

1,tcp協議通訊 現在有兩台電腦a和b。在 假設a的位址為 192.168.0.100 假設b的位址為 192.168.0.102 a想給b傳送乙個字串hello,如果a,b之間採用tcp協議,那麼b收到hello的過程是怎樣的呢?首先建立連線 3次握手成功之後,a和b的鏈結才算成功 然後a在給b...

UDP打洞原理

許多p2p軟體比如skype,qq,電驢之類需要不同內網的兩台機子進行通訊,而路由器的nat機制決定了內網訪問外網容易,而外網訪問內網困難,那如何才能做到這一點呢?有辦法 打洞 具體實現方法需要一台伺服器,現在假設兩台內網pc,a和b想用埠40000通訊,閘道器分別為nata,natb.伺服器為s,...