对于一个类项目,我正在用Java编写一个FTP客户端(不允许外部FTP库),它可以连接并从学校的FTP服务器中获取文件。由于某种原因,一旦传输完成,服务器将不会发送226,也不会从它自己的端关闭连接。
使服务器发送226的唯一方法是手动关闭来自客户端的InputStream,这似乎是不安全的,因为客户端在文件传输完成后无法100%确定。 (现在,InputStream的available()方法用于检查传输的距离。)
在项目规范中,它表示我们必须遵循适用于我们正在实施的命令子集的RFC要求。 RFC声明:
通常,服务器负责维护数据 连接 - 启动它并关闭它。例外 是用户DTP以传输模式发送数据的时候 要求关闭连接以指示EOF。服务器 必须在以下条件下关闭数据连接: 1.服务器已完成以传输模式发送数据 需要接近表示EOF。 2.服务器从用户接收ABORT命令。 3.端口规范由来自的命令更改 用户。 4.控制连接合法或以其他方式关闭。 5.发生不可恢复的错误情况。 否则关闭是一个服务器选项,其中的运动 服务器必须通过250或226指示用户进程 仅回复。
这里有什么我想念的吗?
编辑:运行的服务器是ProFTPD 1.3.0a服务器。
答案 0 :(得分:0)
Anon,
这篇文章只是我个人的意见。
我是你的大学讲师我很高兴如果你在客户那边关闭了明显被挖出来的小溪,然后处理了随后的226 ...就像你刚才所说的一样,特别指出它是学校FTP服务明显偏离已发布的协议的“解决方法”。即:“不是我的问题,我只需处理它.K老板?”
获得三重奖励单词分数: 1.编写您的客户端以使用标准服务器(在您的盒子上运行的FTP服务器进行测试,每个操作系统都有免费的服务器)以及您的学校“显然是狡猾的”FTP服务器...和 2.确切了解学校的FTP服务器是什么(10美元说它是一些自己生产的超级标准的非标准极值的教授),然后看看你是否可以确认这是一个已知问题的实施...如果不是,则向作者提交错误报告。
我只是猜测这是教授的“尾巴扭曲”......看看谁是“现实世界的挑战”。
干杯。基思。
答案 1 :(得分:0)
您使用的传输模式是什么?引用RFC959:
流传输模式本质上是 不可靠,因为一个人不能 确定连接是否关闭 过早与否。另一个 传输模式(Block,Compressed)做 不要关闭连接以表明 文件的结尾。他们有足够的FTP 编码数据连接可以 被解析以确定结束 文件。因此可以使用这些模式 保持数据连接打开 多个文件传输。
您使用的是Block还是Compressed?
编辑 - 哦 - 流
我没有在第一次阅读时接受它,但是你说你正在使用InputStream.available()
来查看转移到底有多远?这不是那种方法的作用。在这种情况下,它返回计算机已收到但尚未由应用程序处理的字节数。返回的值可以是从零到文件的完整大小。
如果您假设文件在available()
返回0时完全发送,则表示您过早停止读取 - 这就是服务器未关闭套接字并发送226的原因。
判断文件是否完全发送的唯一方法是测试来自流的read
操作的返回。如果为-1,则文件完成。读入字节数组可以读取零字节。这是不寻常的,但允许。在输入关闭之前从输入流读取的典型代码如下所示:
byte[] buffer = new byte[0x1000];
int read;
while( (read=in.read(buffer)) != -1 ) {
System.out.println("Read "+read +" bytes from socket ("+
in.available()+" available now)");
}