# 从零开始的 HTTP 链接

0 号端口是保留端口，大部分应用程序会认为 0 号端口无效从而拒绝连接。但是，TCP 数据包头部的端口字段是两个字节，可以表示 0~65535 的端口号，所以构造 0 号端口的数据包是完全可行的。

经过我的测试，在大多数网络环境下，包括校园网、家庭宽带、国内外的云服务器等，即使经过了家用路由器的 NAT，0 号端口的流量也都是可以正常通过的。少数网络环境可能封禁了 0 号端口的流量，此时你可能需要更换一个网络环境或者从云服务器（包括一些免费的持续集成和沙箱环境等）发起连接。

## 简单的解法

在 Linux 下，安装 socat，然后运行 `socat TCP-LISTEN:20000,fork,reuseaddr TCP:202.38.93.111:0`，再从浏览器访问 localhost:20000 即可。（注：这里的 20000 也可以换成其他端口号，与下文「花絮」中提到的 20000 没有关系）

要注意，如果你在用 Linux 虚拟机，很多虚拟机软件的 NAT 实现不能正确处理 0 号端口，你需要把虚拟机的网络设置从 NAT 模式改为桥接模式。

## 其他理论上可行的解法

- 直接在 Linux 上使用 socket 编程来连接，socket 相关的函数没有限制 0 号端口的使用
- 使用比较古老版本的 curl 工具，curl 的较旧版本遇到 0 号端口时不会报错退出
- 修改浏览器源代码直接去掉相关限制
- 使用 scapy 来直接构造数据包
- 使用 iptables 等工具修改目标端口
- 修改 Linux 内核

## 花絮：服务器是如何部署的？

服务器上这个网站在 20000 端口提供服务，然后我加了两条 iptables：

```
iptables -t nat -I PREROUTING -p tcp --dport 20000 -j REDIRECT --to-port 0
iptables -t nat -I PREROUTING -p tcp --dport 0 -j REDIRECT --to-port 20000
```

相当于把 20000 端口的流量与 0 端口的流量互换了一下
