Example #1
0
 bool SendMessageToServerAndWaitReply(string msg)
 {
     try
     {
         MyFTPHelper.WriteToNetStream(msg, controlStream);
         ReadServerReply();
         return(true);
     }
     catch (Exception exc)
     {
         if (exc.GetType() == typeof(IOException))
         {
             serverDisconnectEvent(this, new EventArgs());
         }
         PostMessageToConsoleWithLock(exc.Message);
         return(false);
     }
 }
Example #2
0
        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;
                }
            }
        }