我必须从 ftp 服务器获取文件,但我遇到了一些特定的问题。代码的大致思路是,我必须登录 3 次,然后从服务器获取文件列表。顺利通过,但是当我访问我需要的两个文件时,我得到一个 SocketException:“已建立的连接被主机中的软件中止”
需要明确的是,第一个文件不会生成此异常,但它也不会下载任何内容。第二个完全失败。
代码如下:
static void Main(string[] args)
{
IPHostEntry dns = Dns.GetHostEntry("SERVER");
IPEndPoint serverIP = new IPEndPoint(dns.AddressList[0], 21);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(serverIP);
FTPRequest("USER firstusername\n", sock);
FTPRequest("PASS firstpass\n", sock);
FTPRequest("USER secondusername\n", sock);
FTPRequest("PASS secondpass\n", sock);
FTPRequest("USER thirdusername\n", sock);
FTPRequest("PASS thirdpass\n", sock);
FTPRequest("TYPE A\n", sock);
string s = FTPRequest("PASV\n", sock);
IPEndPoint listenIP = IPEnd(s);
Socket sock2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock2.Connect(listenIP);
FTPRequest("LIST\n", sock);
ArrayList al = new ArrayList();
try
{
byte[] buffer = new byte[25000];
int bytes = 0;
bytes = sock2.Receive(buffer);
Thread.Sleep(1000);
string stringList = Encoding.ASCII.GetString(buffer, 0, bytes);
foreach (string st in stringList.Split(' ', '\n'))
{
if (st.Contains(".CSV"))
al.Add(st.Trim());
}
}
catch (Exception)
{
return;
}
sock2.Disconnect(false);
DateTime dt = new DateTime();
foreach (string st in al)
{
DateTime temp = DateTime.ParseExact(st.Split('_', '.')[4], "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
if (temp > dt)
dt = temp;
}
string file1 = "";
string file2 = "";
foreach (string st in al)
{
if (st.Contains(dt.ToString("yyyyMMdd")))
{
if (st.Contains("CAN"))
file1 = st;
else
file2 = st;
}
}
FTPRequest("TYPE I\n", sock);
foreach (string file in new string[] { file1, file2 })
{
if (file != "")
{
Socket sock3 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
FTPRequest("TYPE I\n", sock);
sock3.Connect(IPEnd(FTPRequest("PASV\n", sock)));
FTPRequest("RETR" + file + '\n', sock);
try
{
byte[] buffer = new byte[25000];
int bytes = 0;
bytes = sock3.Receive(buffer);
FileStream writeStream = new FileStream(@"MYPATH" + file1, FileMode.Create);
while (bytes > 0)
{
writeStream.Write(buffer, 0, bytes);
bytes = sock3.Receive(buffer, 0);
}
}
catch (Exception)
{
return;
}
finally
{
sock3.Disconnect(false);
}
}
}
sock.Disconnect(false);
Console.Read();
}
static string FTPRequest(string command, Socket sock)
{
string resp = string.Empty;
Byte[] bytesReceived = new Byte[1024];
int bytes = 0;
Byte[] bytesSent = Encoding.ASCII.GetBytes(command);
sock.Send(bytesSent, bytesSent.Length, 0);
Thread.Sleep(1000);
try
{
bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0);
}
catch (Exception)
{
}
return Encoding.ASCII.GetString(bytesReceived, 0, bytes);
}
static IPEndPoint IPEnd(string pasvResponse)
{
string s = pasvResponse.Split(' ')[4];
s = s.Trim();
s = s.Trim('(', ')');
string[] sp = s.Split(',');
IPHostEntry dns = new IPHostEntry();
try
{
dns = Dns.Resolve(string.Format("{0}.{1}.{2}.{3}", sp[0], sp[1], sp[2], sp[3]));
}
catch (Exception)
{
}
int port = int.Parse(sp[4]) * 256 + int.Parse(sp[5]);
return new IPEndPoint(dns.AddressList[0], port);
}
我对将 c# 用于 FTP 的东西有点陌生,所以非常感谢任何帮助。