依雲posted @ 2 年前 in 網路 with tags python
網路socat
udp , 7095 閱讀
兩台沒有外網 ip、在 nat 後邊的主機如何直連?udp打洞通常可行,但是需要第三方伺服器。方法如下:
在伺服器 s 上監聽乙個 udp 埠,在收到 udp 資料報後把源位址發回去。**如下(github):
udpaddr12
3456
78910
1112
1314
1516
1718
1920
21import
sys
import
time
import
socket
def
main(port):
s
=
socket.socket(socket.af_inet, socket.sock_dgram)
s.bind(('', port))
try
:
while
true
:
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
=
'')
except
keyboardinterrupt:
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,...