Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在FTP服务器(PASV)上使用RETR时如何确定文件的结尾_C#_Sockets_Ftp - Fatal编程技术网

C# 在FTP服务器(PASV)上使用RETR时如何确定文件的结尾

C# 在FTP服务器(PASV)上使用RETR时如何确定文件的结尾,c#,sockets,ftp,C#,Sockets,Ftp,我决定在C#中使用我自己的FTP套接字客户端,以获得更多的控制,但主要是为了学习体验。但我无法计算在发出RETR命令后需要读取多少文件数据。我能够建立最初的FTP通信连接,然后通过发出PASV命令和所有好的东西在新端口上连接第二个套接字 我的问题是,当我在通信端口上发出RETR命令时,FTP服务器开始通过被动端口发送文件,然后在通信端口上完成发送时发出226命令。我可以很好地接收数据,但有时226命令会在所有文件数据到达被动端口之前到达通信端口。因此,如果我在获得226命令后立即向被动套接字任务

我决定在C#中使用我自己的FTP套接字客户端,以获得更多的控制,但主要是为了学习体验。但我无法计算在发出RETR命令后需要读取多少文件数据。我能够建立最初的FTP通信连接,然后通过发出PASV命令和所有好的东西在新端口上连接第二个套接字

我的问题是,当我在通信端口上发出RETR命令时,FTP服务器开始通过被动端口发送文件,然后在通信端口上完成发送时发出226命令。我可以很好地接收数据,但有时226命令会在所有文件数据到达被动端口之前到达通信端口。因此,如果我在获得226命令后立即向被动套接字任务发出停止读取的信号,它有时会丢失包含文件结尾的数据。我已尝试检查套接字。在退出套接字之前可用。接收循环但通常不是套接字。可用将报告套接字上可用的0字节,但使用套接字并不意味着没有更多数据。在阅读FTP规范时,似乎FTP服务器应该在完成所有数据发送后关闭数据连接,但我认为这不会发生。我可以整天循环读取0字节的数据。我是在看一个坏掉的FTP服务器,还是我的方法有问题


现在来了解一些可能是我问题答案的其他信息。使用连接到同一FTP服务器的Filezilla,我看到当请求文件时,FTP服务器会将文件长度附加到括号中的150命令。例如,“150打开test.zip的二进制模式数据连接(123421字节)。”此文本是FTP标准的一部分吗?如果所有FTP服务器都使用相同的行为和格式,那么我可以一直读取,直到达到123421字节。但如果这不是常见的行为,那我就回到原点了。非常感谢您的建议。

我似乎没有很好地阅读规范,因为RFC 3659中有一个SIZE命令将返回文件的大小。我测试了它,它会完全满足我的需要

我无法计算在发出RETR命令后需要读取多少文件数据

这取决于传输模式(见第3.4节)

在流模式下(通常情况下),文件的结尾由发送方关闭数据套接字表示。这意味着数据连接不能重复用于多次传输

在块模式下,数据以块的形式发送,发送方将在传输结束时发送一个EOF块。这使得数据连接可以重复用于多次传输

我的问题是,当我在通信端口上发出RETR命令时,FTP服务器开始通过被动端口发送文件,然后在通信端口上完成发送时发出226命令。我可以很好地接收数据,但有时226命令会在所有文件数据到达被动端口之前到达通信端口

在完成传输端口上的数据读取之前,不要读取通信端口上的响应

因此,如果我在获得226命令后立即向被动套接字任务发出停止读取的信号,它有时会丢失包含文件结尾的数据

所以不要发信号让你的插座停止读取。让它自己停止阅读

我已尝试检查套接字。在退出套接字之前可用。接收循环但通常不是套接字。可用将报告套接字上可用的0字节,但使用套接字并不意味着没有更多数据

对<代码>可用只是报告此时等待读取的字节数。继续阅读,直到
Receive()
告诉您实际发生了断开连接。如果要在调用
Receive()
之前轮询套接字状态,请使用
poll()
,断开连接将报告为可读状态。无论哪种方式,
Receive()
都将在正常断开连接时返回0字节,并在异常断开连接时引发异常

阅读FTP规范,似乎FTP服务器应该在完成所有数据发送后关闭数据连接

在流模式下,是的

但我认为这种情况不会发生

是的

我可以整天循环读取0字节的数据。我是在看一个坏掉的FTP服务器,还是我的方法有问题

你的方法有问题

使用连接到同一FTP服务器的Filezilla,我看到当请求文件时,FTP服务器会将文件长度附加到括号中的150命令。例如,“150打开test.zip的二进制模式数据连接(123421字节)。”此文本是FTP标准的一部分吗

不,不是。文本是任意的,它可以是服务器想要的任何内容。重要的是响应代码(150)指示传输正在进行

如果所有FTP服务器使用相同的行为和格式

它们不使用相同的文本格式

然后我可以一直读到123421字节


您应该一直读取,直到服务器关闭数据连接。然后读取通信端口上的最终响应,以确保服务器认为传输成功,而不是过早中止。

并非所有服务器都支持
大小,因为直到2005年才对其进行标准化。为了简单地检测EOF,传输模式本身足以告诉您传输何时完成。见第3.4节。在流模式下(通常情况下),文件的结尾由发送方关闭数据套接字表示(是的,服务器将关闭)