How to send arbitrary FTP commands in C#

后端 未结 4 1051
隐瞒了意图╮
隐瞒了意图╮ 2020-12-03 15:46

I have implemented the ability to upload, download, delete, etc. using the FtpWebRequest class in C#. That is fairly straight forward.

What I need to d

4条回答
  •  春和景丽
    2020-12-03 16:22

    The FtpWebRequest won't help you as Thomas Levesque has said in his answer. You can use some third party solutions or the following, simplified TcpClient based code which I have refactored from an answer written in Visual Basic:

    public static void SendFtpCommand()
    {
        var serverName = "[FTP_SERVER_NAME]";
        var port = 21;
        var userName = "[FTP_USER_NAME]";
        var password = "[FTP_PASSWORD]"
        var command = "SITE CHMOD 755 [FTP_FILE_PATH]";
    
        var tcpClient = new TcpClient();
        try
        {
            tcpClient.Connect(serverName, port);
            Flush(tcpClient);
    
            var response = TransmitCommand(tcpClient, "user " + userName);
            if (response.IndexOf("331", StringComparison.OrdinalIgnoreCase) < 0)
                throw new Exception(string.Format("Error \"{0}\" while sending user name \"{1}\".", response, userName));
    
            response = TransmitCommand(tcpClient, "pass " + password);
            if (response.IndexOf("230", StringComparison.OrdinalIgnoreCase) < 0)
                throw new Exception(string.Format("Error \"{0}\" while sending password.", response));
    
            response = TransmitCommand(tcpClient, command);
            if (response.IndexOf("200", StringComparison.OrdinalIgnoreCase) < 0)
                throw new Exception(string.Format("Error \"{0}\" while sending command \"{1}\".", response, command));
        }
        finally
        {
            if (tcpClient.Connected)
                tcpClient.Close();
        }
    }
    
    private static string TransmitCommand(TcpClient tcpClient, string cmd)
    {
        var networkStream = tcpClient.GetStream();
        if (!networkStream.CanWrite || !networkStream.CanRead)
            return string.Empty;
    
        var sendBytes = Encoding.ASCII.GetBytes(cmd + "\r\n");
        networkStream.Write(sendBytes, 0, sendBytes.Length);
    
        var streamReader = new StreamReader(networkStream);
        return streamReader.ReadLine();
    }
    
    private static string Flush(TcpClient tcpClient)
    {
        try
        {
            var networkStream = tcpClient.GetStream();
            if (!networkStream.CanWrite || !networkStream.CanRead)
                return string.Empty;
    
            var receiveBytes = new byte[tcpClient.ReceiveBufferSize];
            networkStream.ReadTimeout = 10000;
            networkStream.Read(receiveBytes, 0, tcpClient.ReceiveBufferSize);
    
            return Encoding.ASCII.GetString(receiveBytes);
        }
        catch
        {
            // Ignore all irrelevant exceptions
        }
    
        return string.Empty;
    }
    

    You can expect the following flow while getting through the FTP:

    220 (vsFTPd 2.2.2)
    user [FTP_USER_NAME]
    331 Please specify the password.
    pass [FTP_PASSWORD]
    230 Login successful.
    SITE CHMOD 755 [FTP_FILE_PATH]
    200 SITE CHMOD command ok.
    

提交回复
热议问题