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); } }
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; } } }