起因
最近在自己写一些玩具,然后需要用到FTP文件上传,理论上需要面向百度搭建FTP服务器以及找一下子FTP文件上传代码。
但是呢,突然想起来自己曾经心血来潮在腾讯云上搞了一台廉价服务器玩 (我不是打广告,我也不配打广告)闲置这台服务器也有点浪费,就百度了一下腾讯云服务器宝塔面板如何安装FTP服务器(这里还是要打广告的,虽然没给钱,非常推荐 对linux/docker/k8s不太熟悉,且有远大理想,且...... 的初中级java开发使用)然后一键安装完了。就搞文件上传嘛。
写代码 !!!
这里十分感谢 掘金搜索 VeggieOrz 这位ios开发工程师提供的ftp服务器文件的博文,让我避免了很多的代码坑,当然 代码我是不会提供的,毕竟我是一个懒得贴代码的初级开发人员这里纯粹是为了感谢这位提供了FTP文件上传文章的 ※ 同志 ※ !!!如有冒犯,在这里直接双膝跪地道歉
发生问题了!!!
写过FTP文件上传的开发应该了解,ftp文件服务器文件上传分几个步骤
1.链接ftp服务器
2.登录ftp服务器
3.判断是否链接成功
4.判断上传路径是否存在
5.上传文件
6.关闭ftp服务链接
大概是以上几步,我的问题 发生在,第五步 上传文件,报链接超时
排查问题
在我历史的开发生涯中,关于连接服务器排查的点如下
1.检查是否能ping通
2.检查f服务器的访问端口是否对外打开
这两个,尝试了一下,都没什么问题
那这两个没问题,我就暂时抛弃了关于服务器方向的排查,专心鼓捣关于服务器内部的FTP服务器的问题排查,因为部分博文中都提到 需要将 ftp服务器开启读和写操作 才能完成文件上传
这里也要吐槽一下``宝塔面板``,你也不告诉我,就帮我开开启了读写权限,让我很是尴尬的找了半天欸
那确定了读写权限开启,接下来是测试ftp服务器是否在本地通过cmd窗口可以进行文件上传
这里通过cmd窗口以及命令行成功上传文件至 ftp服务器
然后我就愣住了。。。。。。常规的文件上传试了,没问题,
读写权限开启了也没问题,难不成还是服务器问题?
然后我就这这个ftpClient的上传代码 往下面debug了几层,debug几次后,发现了一个神奇的事情。
关于ftp服务器的原生代码我是不太懂的,但是port这个参数 很简单就可以理解为,端口 在debug的代码中 具体的port点我忘了,但是是在创建链接下面的一个代码里
然后,我就问了一下伟大的人工智能,
在将输入流上传到FTP服务器的过程中,本地和FTP服务器之间会发生什么交互
人工智能回答:
在将输入流上传到FTP服务器的过程中,本地和FTP服务器之间会发生以下交互:
1. 客户端随机打开一个本地大于1024的端口P1。
2. 客户端通过端口P1向服务器控制端口(端口21)发起连接请求。
3. 服务器进行认证成功,请求建立。
4. 客户端对本地端口P2进行监听并向服务器发送“Port P1+1”,告诉服务器客户端的数据监听端口。
5. 服务器返回“227 Entering Passive Mode (h1,h2,h3,h4,p1)”,其中h1-h4是四个用于数据传输的临时端口号。
6. 客户端向服务器发送“PORT p1,p2,p3,p4”以选择其中一个端口进行数据传输。
7. 服务器返回“227 Entering Extended Status Mode”。
8. 客户端发送“TYPE I”以设置传输类型为二进制。
9. 客户端发送“STOR filename”以上传文件。
10. 服务器返回“226 File status okay; about to open data connection.”
11. 客户端开始读取本地文件内容并将其写入到与FTP服务器建立的连接中。
12. 文件上传完成后,客户端断开与FTP服务器的连接。
在以上过程中,很容易就看到了,服务端会向客户端返回h1~h4四个临时端口号 然后由ftpclient去选择端口号进行传输。
然后,我突然意识到,我可能对返回的服务端口号没打开关于防火墙,然后检查了一下 腾讯云和宝塔面板的端口
选择了打开39000-40000的 端口范围区间 然后启动test类 进行测试,
上传成功!!!!!
总结
确实没想到最后还是服务器的问题,我认知中,关于服务器交互一直只是,创建连接,然后就可以直接上传了,而且依托的还是 一定会开放的 21 端口 没想到还有随机端口的概念出现 确实学到了
在此感谢!! 腾讯云,宝塔面板,ftpClient以及 VeggieOrz这位博主 让我遇到了这种神奇的bug,同时让我的生活丰富多彩