コード例 #1
0
ファイル: FTPClient.cs プロジェクト: StellarYan/MyFTP
        public FTPClient(IPAddress serverIP, int localControlPort, string user, string password, Action <string> ConsoleLogDelegate)
        {
            controlClient    = new TcpClient();
            dataClient       = new TcpClient();
            ConsoleLogEvent += ConsoleLogDelegate;
            controlPort      = localControlPort;
            dataPort         = controlPort + 1;
            try
            {
                controlClient.Connect(serverIP, MyFTPHelper.ftpControlPort);
                controlStream = controlClient.GetStream();

                FTPCommand userCommand = new FTPCommand("USER", new string[] { user });
                if (!SendMessageToServerAndWaitReply(userCommand.ToString() + MyFTPHelper.FTPNewLine))
                {
                    return;
                }
                FTPCommand passwordCommand = new FTPCommand("PASS", new string[] { password });
                if (!SendMessageToServerAndWaitReply(passwordCommand.ToString() + MyFTPHelper.FTPNewLine))
                {
                    return;
                }
            }
            catch (Exception exc)
            {
                throw exc;
            }
        }
コード例 #2
0
 public async Task <FTPResponse> SendCommandAsync(FTPCommand command, CancellationToken token = default(CancellationToken))
 {
     return(await SendCommandAsync(new FTPCommandEnvelope
     {
         FtpCommand = command
     }, token));
 }
コード例 #3
0
        public void SendCommand(FTPCommand command, params object[] args)
        {
            string cmd = InterpretCommand(command, args);

            print(">> " + cmd);
            controlConnectionSocket.Send(ToASCII(cmd));
        }
コード例 #4
0
ファイル: MyFTPHelper.cs プロジェクト: StellarYan/MyFTP
    public static FTPCommand?ReadNextCommand(NetworkStream stream)
    {
        if (CachedCommands.Count > 0)
        {
            return(CachedCommands.Dequeue());
        }
        string streamstring = null;

        try
        {
            streamstring = MyFTPHelper.ReadFromNetStream(stream);
        }
        catch (Exception exc)
        {
            throw exc;
        }
        string[] messages = streamstring.Split(new string[] { MyFTPHelper.FTPNewLine }, StringSplitOptions.RemoveEmptyEntries);
        Array.ForEach(messages, (m) => CachedCommands.Enqueue(FTPCommand.String2Command(m)));
        if (CachedCommands.Count > 0)
        {
            return(CachedCommands.Dequeue());
        }
        else
        {
            return(null);
        }
    }
コード例 #5
0
        public void SendCommand(FTPCommand command, bool shouldPrint, params object[] args)
        {
            string cmd = InterpretCommand(command, args);

            if (shouldPrint)
            {
                print(">> " + cmd);
            }
            controlConnectionSocket.Send(ToASCII(cmd));
        }
コード例 #6
0
ファイル: MyFTPHelper.cs プロジェクト: StellarYan/MyFTP
    public static string Command2String(FTPCommand command)
    {
        String s = command.controlCommand;

        if (command.parameters != null)
        {
            Array.ForEach(command.parameters, (p) => s += " " + p);
        }
        return(s);
    }
コード例 #7
0
ファイル: UserInterpreter.cs プロジェクト: math519a/FTP
        public static string InterpretCommand(FTPCommand cmd, params object[] args)
        {
            switch (cmd)
            {
            case FTPCommand.ChangeToParent: return("CDUP");

            case FTPCommand.StructureMount: return("SMNT");

            case FTPCommand.StoreUnique: return("STOU");

            case FTPCommand.RemoveDirectory: return("RMD");

            case FTPCommand.MakeDirectory: return("MKD");

            case FTPCommand.PrintDirectory: return("PWD");

            case FTPCommand.ChangeDirectory: return(string.Format("CWD {0}", args));

            case FTPCommand.System: return("SYST");

            case FTPCommand.User: return(string.Format("USER {0}", args));

            case FTPCommand.ListFiles: return("NLST");

            case FTPCommand.SetPortActive: return(string.Format("PORT {0}", args));

            case FTPCommand.SetPortPassive: return(string.Format("PASV {0}", args));

            case FTPCommand.RetrieveFile:  return(string.Format("RETR {0}", args));

            case FTPCommand.SetTransferMode: return(string.Format("MODE {0}", args));

            case FTPCommand.SetTransferType: return(string.Format("TYPE {0}", args));

            case FTPCommand.AppendFile: return(string.Format("APPE {0}", args));

            case FTPCommand.Put: return(string.Format("STOR {0}", args));

            case FTPCommand.Disconnect: return("QUIT");

            default:
                throw new Exception("Can not interpret this command");
            }
        }
コード例 #8
0
ファイル: MyFTPHelper.cs プロジェクト: StellarYan/MyFTP
    public static FTPCommand String2Command(string s)
    {
        string[]      tokens     = s.Split(' ');
        FTPCommand    cmd        = new FTPCommand();
        List <string> parameters = new List <string>();

        foreach (var token in tokens)
        {
            if (cmd.controlCommand == null)
            {
                cmd.controlCommand = token;
            }
            else
            {
                parameters.Add(token);
            }
        }
        cmd.parameters = parameters.ToArray();
        return(cmd);
    }
コード例 #9
0
        /// <summary>
        /// Opens a filestream to the given filename
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        private async Task <Stream> OpenFileStreamAsync(string fileName, FTPCommand command)
        {
            EnsureLoggedIn();
            Logger?.LogDebug($"[FTPClient] Opening filestream for {fileName}, {command}");
            dataStream = await ConnectDataStreamAsync();

            var retrResponse = await ControlStream.SendCommandAsync(new FTPCommandEnvelope
            {
                FTPCommand = command,
                Data       = fileName
            });

            if ((retrResponse.FTPStatusCode != FTPStatusCode.DATAALREADYOPEN) &&
                (retrResponse.FTPStatusCode != FTPStatusCode.OPENINGDATA) &&
                (retrResponse.FTPStatusCode != FTPStatusCode.CLOSINGDATA))
            {
                throw new FTPException(retrResponse.ResponseMessage);
            }

            return(dataStream);
        }
コード例 #10
0
ファイル: FTPClient.cs プロジェクト: StellarYan/MyFTP
        public void DownLoadFile(string filename, int size)
        {
            FTPCommand portCommand = new FTPCommand("PORT", new string[] { controlPort.ToString() });

            if (!SendMessageToServerAndWaitReply(portCommand.ToString() + MyFTPHelper.FTPNewLine))
            {
                return;
            }
            ListenDataPort();
            PostMessageToConsoleWithLock("开始下载" + filename);
            FTPCommand downloadCommand = new FTPCommand("RETR", new string[] { filename });

            if (!SendMessageToServerAndWaitReply(downloadCommand.ToString() + MyFTPHelper.FTPNewLine))
            {
                return;
            }

            try
            {
                FileStream    fs         = File.OpenWrite(downloadDirectory + filename);
                NetworkStream dataStream = dataClient.GetStream();
                currenttransfer = new FileTransfer()
                {
                    networkStream = dataStream,
                    filestream    = fs,
                };
                currenttransfer.DownloadAsync(() =>
                {
                    fs.Close();
                    dataStream.Close();
                    PostMessageToConsoleWithLock("完成下载");
                });
            }
            catch (Exception exc)
            {
                PostMessageToConsoleWithLock(exc.Message);
            }
        }
コード例 #11
0
ファイル: FTPClient.cs プロジェクト: StellarYan/MyFTP
        public void UploadFile(string filepath)
        {
            FTPCommand portCommand = new FTPCommand("PORT", new string[] { controlPort.ToString() });

            if (!SendMessageToServerAndWaitReply(portCommand.ToString() + MyFTPHelper.FTPNewLine))
            {
                return;
            }
            ListenDataPort();

            PostMessageToConsoleWithLock("开始上传" + Path.GetFileName(filepath));
            FTPCommand uploadCommand = new FTPCommand("STOR", new string[] { Path.GetFileName(Path.GetFileName(filepath)) });

            if (!SendMessageToServerAndWaitReply(uploadCommand.ToString() + MyFTPHelper.FTPNewLine))
            {
                return;
            }
            try
            {
                FileStream    fs         = File.OpenRead(filepath);
                NetworkStream dataStream = dataClient.GetStream();
                currenttransfer = new FileTransfer()
                {
                    networkStream = dataStream,
                    filestream    = fs,
                };
                currenttransfer.UploadAsync(() =>
                {
                    fs.Close();
                    dataStream.Close();
                    PostMessageToConsoleWithLock("完成上传");
                });
            }
            catch (Exception exc)
            {
                PostMessageToConsoleWithLock(exc.Message);
            }
        }
コード例 #12
0
ファイル: FTPClient.cs プロジェクト: StellarYan/MyFTP
        public void UpdateList()
        {
            FTPCommand fileListCommand = new FTPCommand("LIST", null);

            SendMessageToServerAndWaitReply(fileListCommand.ToString() + MyFTPHelper.FTPNewLine);
        }
コード例 #13
0
ファイル: FTPServer.cs プロジェクト: StellarYan/MyFTP
        public void Start()
        {
            while (true)
            {
                try
                {
                    FTPCommand?ncommand = ReadNextCommand();
                    if (ncommand == null)
                    {
                        continue;
                    }
                    else
                    {
                        FTPCommand command = ncommand.Value;
                        FTPReply   reply   = new FTPReply()
                        {
                            replyCode = FTPReply.Code_SyntaxError
                        };
                        switch (command.controlCommand)
                        {
                        case "USER":     //USER 指定账号
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara,
                                };
                                break;
                            }
                            user.username = command.parameters[0];
                            break;

                        case "PASS":     //PASS 指定密码
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara,
                                };
                                break;
                            }
                            user.password = command.parameters[0];
                            if (serverDispatcher.CheckUserWithLock(user))
                            {
                                Logined = true;
                                serverDispatcher.PostMessageFromClient("已成功登录", this);
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_UserLoggedIn,
                                    post      = "login success"
                                };
                            }
                            else
                            {
                                serverDispatcher.PostMessageFromClient("密码或用户名有误", this);
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_UserNotLogIn,
                                    post      = "login fail"
                                };
                            }
                            break;

                        case "LIST":     //LIST 返回服务器的文件目录(标准中不指定返回格式,格式为我们自定义)
                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_FileList,
                                post      = serverDispatcher.GetEncodedFileList()
                            };
                            break;

                        case "STOR":     //STOR 客户端上传文件
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            string        filename           = command.parameters[0];
                            FileStream    downloadFileStream = File.OpenWrite(serverDispatcher.GetCurrentDirectory() + filename);
                            NetworkStream downloadDataStream = dataClient.GetStream();
                            if (downloadFileStream == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            if (dataClient == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_ConnectionClosed
                                };
                                break;
                            }
                            currentTransfer = new FileTransfer()
                            {
                                networkStream = downloadDataStream,
                                filestream    = downloadFileStream,
                            };
                            currentTransfer.DownloadAsync(() =>
                            {
                                downloadDataStream.Close();
                                downloadFileStream.Close();
                                serverDispatcher.PostMessageFromClient("文件上传完成", this);
                            }
                                                          );

                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_ConnectionClosed
                            };
                            break;

                        case "RETR":     //RETR 客户端下载文件
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            FileStream    uploadFileStream = serverDispatcher.OpenFileStreamInfileList(command.parameters[0]);
                            NetworkStream uploadDataStream = dataClient.GetStream();
                            if (uploadFileStream == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            if (dataClient == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_ConnectionClosed
                                };
                                break;
                            }
                            currentTransfer = new FileTransfer()
                            {
                                networkStream = uploadDataStream,
                                filestream    = uploadFileStream,
                            };
                            currentTransfer.UploadAsync(() =>
                            {
                                uploadDataStream.Close();
                                uploadFileStream.Close();
                                serverDispatcher.PostMessageFromClient("文件上传完成", this);
                            }
                                                        );

                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_ConnectionClosed
                            };
                            break;

                        case "ABOR":     //QUIT 关闭与服务器的连接
                            throw new NotImplementedException();

                        case "QUIT":     //ABOR 放弃之前的文件传输
                            throw new NotImplementedException();

                        case "PASV":     //PASV 数据线程让服务器监听特定端口
                            throw new NotImplementedException();

                        case "PORT":     //PORT 客户端的控制端口为N,数据端口为N+1,服务器的控制端口为21,数据端口为20
                            if (command.parameters.Length != 1 || !int.TryParse(command.parameters[0], out controlPort))
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            if (!serverDispatcher.CheckDataPortLegal(controlPort, this))
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            var remoteDataEnd = (IPEndPoint)controlClient.Client.RemoteEndPoint;
                            remoteDataEnd.Port = controlPort + 1;
                            dataClient         = new TcpClient();
                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_DataConnectionOpen
                            };
                            dataClient.ConnectAsync(remoteDataEnd.Address.MapToIPv4(), remoteDataEnd.Port);
                            serverDispatcher.PostMessageFromClient("与" + user.username + "建立数据连接", this);
                            break;

                        default:
                            break;
                        }
                        MyFTPHelper.WriteToNetStream(reply.ToString(), controlStream);
                    }
                }
                catch (System.IO.IOException exc)
                {
                    serverDispatcher.PostMessageFromClient(exc.Message, this);
                    controlClient.Close();
                    controlStream.Close();
                    return;
                }
            }
        }