今晚(确切的来说是『明天凌晨』,当我意识到我所说的『今晚』已经不是『今天』的时候……)在用 FTP 部署新代码的时候发现突然无法上传文件了。
问题症状
具体问题表现是一切连接都正常,可以切换目录、可以删除远程文件、可以下载远程文件,但就是不能上传文件,一选择上传就会卡在『150 接受数据连接』(客户端我使用的是 FileZilla)直到超时重连。
原因定位
起初我怀疑是远程主机出了问题,毕竟是个便宜的 VPS,偶尔抽抽风都习惯了。但是重启了系统并且该 VPS 上的网站都能正常浏览(说明 WEB 服务没有受到影响),似乎不像是服务器的问题。
随后我又试了另一台国内的 FTP 服务器,依然无法上传文件。排除服务器的原因。
接着我开始检查系统设置,OS X 自带的防火墙虽然开启了,但是并没有限制 FileZilla 的网络连接,而且如果限制了,不可能还能连上 FTP 服务器。而且在保证系统设置没有改变的前提下,我之前是成功用 FTP 上传过文件的。因此排除系统防火墙设置问题。
再之后就开始 Google 了,还有一种说法是没有正确的使用 FTP 传输模式。FTP 传输模式包括『主动模式』和『被动模式』,两者 FileZilla 都支持,我都进行了尝试,依然不能上传文件。此外,还需要注意是否设置正确的 FTP 端口号,保不齐不是默认的 21 呢。
问题解决
最后经历了大量的搜索后,终于在 Super User 上找到了解决方案,原来是 MTU 惹的祸。MTU(Maximum Transimission Unit) 是最大传输单元的意思,指的是传输协议规定的最大数据单元的大小。在传输大型文件时,系统需要把文件分割成多个小块进行传输,每一个小块就是一个 Transimission Unit。
根据这篇回答的解释,由于系统设置的 MTU 值大于路由器接受的 MTU 值,导致了文件传输的失败。解决方法也很简单,修改对应网卡的 MTU 值即可。
命令行设置方法
打开终端,输入以下命令查看各网卡的 MTU 值:
ifconfig | grep mtu
你可能会看到多个网卡名及对应的值,如 en0、en1 等,你需要确定哪一个是你的工作网卡。若不能确定则可参考下文的图形化设置方法。
如果网卡的 MTU 值是 1500,则将其修改成 1300,注意修改正确的网卡:
sudo ifconfig en0 mtu 1300
OS X 设置方法
『系统偏好设置』-『网络』- 在左侧选择你当前的工作网卡 - 『高级』-『硬件』