惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
J
Java Code Geeks
小众软件
小众软件
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
腾讯CDC
T
The Blog of Author Tim Ferriss
大猫的无限游戏
大猫的无限游戏
量子位
M
MIT News - Artificial intelligence
Last Week in AI
Last Week in AI
L
LangChain Blog

依云's Blog

Wayfire支持不缩放Xwayland啦 - 依云's Blog 使用wayvnc远程访问无头Wayfire会话 - 依云's Blog pacfiles: 高速的 pacman -F 替代品 用 Android 手机当电脑的话筒 - 依云's Blog 使用 ffmpeg 对音频文件进行响度归一化 - 依云's Blog 使用 nftables 屏蔽大量 IP - 依云's Blog YubiKey 初体验 - 依云's Blog fcitx5 码表同步方案 - 依云's Blog 我正在使用的火狐扩展(2024年版) - 依云's Blog 使用 PipeWire 实现自动应用均衡器 如果你发现你的 OOM Killer 在乱杀进程 使用 atuin 管理 shell 命令历史 btrfs 元数据满了怎么办 btrfs 翻车记 在 nspawn 里运行 docker Linux 上的字体配置与故障排除 新的 PaddleOCR 部署方案 使用 EasyEffects 调整 Bose 音箱的体验 让离线软件真正离线 我所讨厌的网页行为 tmux 状态栏优化 Google Chrome 中的字体设置 从 getmail6 到 offlineimap 微信消息通知的困扰 Qt 的字体渲染问题 Wayfire 迁移进展(四):不那么 high 的 DPI Wayfire 迁移进展(二):Xwayland HiDPI 以及 waybar Wayfire 迁移进展 不同情况下的图形效果 Wayland 初体验
UDP打洞实验
依云 · 2012-08-28 · via 依云's Blog

两台没有外网 IP、在 NAT 后边的主机如何直连?UDP打洞通常可行,但是需要第三方服务器。方法如下:

在服务器 S 上监听一个 UDP 端口,在收到 UDP 数据包后把源地址发回去。代码如下(github):

import 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.argv[1]))
  except (ValueError, IndexError):
    sys.exit('which port to listen?')

主机 A 发送数据包:

$ 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 是完全圆锥型的。

在知道 A 的发送地址后,主机 B 就可以向这个地址发送数据了。接下来的操作使用 socat 命令就是:

# host A
$ socat readline udp-listen:4567
# host B
$ socat readline udp:A:4567

然后 B 先发送数据让 A 知道 B 的地址(socat 会 connect 到这个地址),双方就可以相互通信了。当然,因为是 UDP 协议,所以通信是不可靠的,丢包啊乱序啊都有可能。

2013年10月13日更新:想要连接到 NAT 后边的 mosh 请看这里