FTP协议旨在支持控制通道,并使用该控制通道告诉服务器打开TCP连接并传输文件。
发送或接收文件的服务器不必与FTP控制通道所连接的服务器相同。它可以是一个三角形"类型连接。
它还允许客户端在控制通道上登录一次,并反复告诉服务器传输文件,而无需重新登录控制通道。
显然,这个概念在创建C#FtpWebRequest
类时已完全逃脱了MS。
我需要完成FTP协议的设计目的:
连接服务器
传递凭据
创建目录(并乐意忽略“已存在'错误”)
反复将文件传输到服务器
退出控制频道
我确定在FtpWebRequest
课程中没有看到这种能力。或任何看似允许C#代码中的那种流的东西。
我看过了:
等。
但这似乎都没有让控制方式符合原样。
我可以指定KeepAlive
属性,但循环必须重复调用WebRequest.Create(targetName);
函数,这将创建一个新连接,并获得一个新响应。然后它们会超出范围或成为孤儿,因此根据定义,它们会被销毁。因此必须关闭连接,然后必须重新打开。对于数据连接,没关系,但操作CONTROL端口的能力在哪里?
该类不允许用户区分CONTROL端口和DATA端口,如FTP规范所定义。
有没有办法使用C#类按原来的方式进行FTP?因为在微软的狭隘思维模式中,整个世界看起来像是一个HTTP Get / Response协议。
感谢任何建议。
-Scotty
答案 0 :(得分:1)
FtpWebRequest
在连接池之上工作。因此,只要FtpWebRequest.KeepAlive
设置为默认值true
,就会隐式重用基础FTP连接。
当KeepAlive
设置为true
时,当请求完成时,基础FTP(控制)连接未关闭。当您使用相同的主机,端口和用户名创建FtpWebRequest
的另一个实例时,将重复使用先前请求的连接。
将两个文件上传请求的这个简单示例带到同一个FTP服务器:
WebRequest request1 = WebRequest.Create("ftp://ftp.example.com/file1.zip");
request1.Credentials = new NetworkCredential("username", "password");
request1.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(@"C:\path\file1.zip"))
using (Stream ftpStream = request1.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
WebRequest request2 = WebRequest.Create("ftp://ftp.example.com/file2.zip");
request2.Credentials = new NetworkCredential("username", "password");
request2.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(@"C:\path\file2.zip"))
using (Stream ftpStream = request2.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
如果您enable .NET network logging,您将看到只有一个FTP控制连接被打开到服务器:
FtpWebRequest#45004109::.ctor(ftp://ftp.example.com/file1.zip)
FtpWebRequest#45004109::GetRequestStream(Method=STOR.)
Current OS installation type is 'Client'.
RAS supported: True
FtpControlStream#21454193 - Created connection from 127.0.0.1:60360 to 93.184.216.34:2121.
Associating FtpWebRequest#45004109 with FtpControlStream#21454193
FtpControlStream#21454193 - Received response [220 ...]
FtpControlStream#21454193 - Sending command [USER username]
FtpControlStream#21454193 - Received response [331 Password required for username]
FtpControlStream#21454193 - Sending command [PASS ********]
FtpControlStream#21454193 - Received response [230 Logged on]
FtpControlStream#21454193 - Sending command [OPTS utf8 on]
FtpControlStream#21454193 - Received response [202 UTF8 mode is always enabled. No need to send this command.]
FtpControlStream#21454193 - Sending command [PWD]
FtpControlStream#21454193 - Received response [257 "/" is current directory.]
FtpControlStream#21454193 - Sending command [TYPE I]
FtpControlStream#21454193 - Received response [200 Type set to I]
FtpControlStream#21454193 - Sending command [PASV]
FtpControlStream#21454193 - Received response [227 Entering Passive Mode (93,184,216,34,247,106)]
FtpControlStream#21454193 - Sending command [STOR file1.zip]
FtpControlStream#21454193 - Received response [150 Opening data channel for file upload to server of "/file1.zip"]
FtpControlStream#21454193 - Received response [226 Successfully transferred "/file1.zip"]
FtpWebRequest#45004109::(Releasing FTP connection#21454193.)
FtpWebRequest#58870012::.ctor(ftp://ftp.example.com/file2.zip)
FtpWebRequest#58870012::GetRequestStream(Method=STOR.)
Associating FtpWebRequest#58870012 with FtpControlStream#21454193
FtpControlStream#21454193 - Sending command [PASV]
FtpControlStream#21454193 - Received response [227 Entering Passive Mode (93,184,216,34,247,142)]
FtpControlStream#21454193 - Sending command [STOR file2.zip]
FtpControlStream#21454193 - Received response [150 Opening data channel for file upload to server of "/file2.zip"]
FtpControlStream#21454193 - Received response [226 Successfully transferred "/file2.zip"]
FtpWebRequest#58870012::(Releasing FTP connection#21454193.)
答案 1 :(得分:-2)