您的当前位置:首页网络编程-实验报告

网络编程-实验报告

2022-12-30 来源:飒榕旅游知识分享网
 贵州大学实验报告

学院:计算机学院 专业:软件工程 班级:软件123班

姓名 实验时间 实验项目名称 实验目的 实验*** 2015-5-9 学号 指导教师 *** 蔡丽 实验组 成绩 FTP上传下载器编程 通过本实验掌握C#中FTP上传下载器编程的方法,了解其区别与适用场合。 了解C#的UDP编程方法。 要求 实验原理 实验使用.NET请求/响应模型的FtpWebRequest类和FtpWebResponse类实现简单的Web浏览器 Visual Studio开发环境 环境 实验步骤 1. 设计程序界面。 2. 实现程序功能。 )))))) 实验内容 实现简单的Web浏览器,要求使用.NET请求/响应模型的FtpWebRequest类和FtpWebResponse类。 服务器核心代码 //FtpServerForm类: using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; 实验数据 using System.Net.Sockets; using System.Threading; using System.Windows.Forms; namespace FtpServer { public partial class FtpServerForm : Form { TcpListener myTcpListener = null; private Thread listenThread; )))))) // 保存用户名和密码 Dictionary users; public FtpServerForm() { InitializeComponent(); // 初始化用户名和密码 users = new Dictionary(); users.Add(\"admin\ // 设置默认的主目录 tbxFtpRoot.Text = \"F:/MyFtpServerRoot/\"; IPAddress[] ips = Dns.GetHostAddresses(\"\"); tbxFtpServerIp.Text = ips[1].ToString(); tbxFtpServerPort.Text = \"21\"; lstboxStatus.Enabled = false; } // 启动服务器 private void btnFtpServerStartStop_Click(object )))))) sender, EventArgs e) { if (myTcpListener == null) { listenThread = new Thread(ListenClientConnect); listenThread.IsBackground = true; listenThread.Start(); lstboxStatus.Enabled = true; lstboxStatus.Items.Clear(); lstboxStatus.Items.Add(\"已经启动Ftp服务...\"); btnFtpServerStartStop.Text = \"停止\"; } else { myTcpListener.Stop(); myTcpListener = null; listenThread.Abort(); lstboxStatus.Items.Add(\"Ftp服务已停止!\"); )))))) lstboxStatus.TopIndex = lstboxStatus.Items.Count - 1; btnFtpServerStartStop.Text = \"启动\"; } } // 监听端口,处理客户端连接 private void ListenClientConnect() { myTcpListener = new TcpListener(IPAddress.Parse(tbxFtpServerIp.Text), int.Parse(tbxFtpServerPort.Text)); // 开始监听传入的请求 myTcpListener.Start(); AddInfo(\"启动FTP服务成功!\"); AddInfo(\"Ftp服务器运行中...[点击”停止“按钮停止FTP服务]\"); while (true) { try { )))))) // 接收连接请求 TcpClient tcpClient = myTcpListener.AcceptTcpClient(); AddInfo(string.Format(\"客户端({0})与本机({1})建立Ftp连接cpClient.Client.RemoteEndPoint, myTcpListener.LocalEndpoint)); User user = new User(); user.commandSession = new UserSeesion(tcpClient); user.workDir = tbxFtpRoot.Text; Thread t = new Thread(UserProcessing); t.IsBackground = true; t.Start(user); } catch { break; } } } )))))) // 处理客户端用户请求 private void UserProcessing(object obj) { User user = (User)obj; string sendString = \"220 FTP Server v1.0\"; RepleyCommandToUser(user, sendString); while (true) { string receiveString = null; try { // 读取客户端发来的请求信息 receiveString = user.commandSession.streamReader.ReadLine(); } catch(Exception ex) { if (user.commandSession.tcpClient.Connected == false) { AddInfo(string.Format(\"客户端({0}断开连接!)\)))))) user.commandSession.tcpClient.Client.RemoteEndPoint)); } else { AddInfo(\"接收命令失败!\" + ex.Message); } break; } if (receiveString == null) { AddInfo(\"接收字符串为null,结束线程!\"); break; } AddInfo(string.Format(\"来自{0}:[{1}]\user.commandSession.tcpClient.Client.RemoteEndPoint, receiveString)); )))))) // 分解客户端发来的控制信息中的命令和参数 string command = receiveString; string param = string.Empty; int index = receiveString.IndexOf(' '); if (index != -1) { command = receiveString.Substring(0, index).ToUpper(); param = receiveString.Substring(command.Length).Trim(); } // 处理不需登录即可响应的命令(这里只处理QUIT) if (command == \"QUIT\") { // 关闭TCP连接并释放与其关联的所有资源 user.commandSession.Close(); return; } )))))) else { switch (user.loginOK) { // 等待用户输入用户名: case 0: CommandUser(user, command, param); break; // 等待用户输入密码 case 1: CommandPassword(user, command, param); break; // 用户名和密码验证正确后登陆 case 2: switch (command) { case \"CWD\": CommandCWD(user, )))))) param); break; case \"PWD\": CommandPWD(user); break; case \"PASV\": CommandPASV(user); break; case \"PORT\": CommandPORT(user, param); break; case \"LIST\": CommandLIST(user, param); break; case \"NLIST\": CommandLIST(user, param); break; // 处理下载文件命令 case \"RETR\": )))))) CommandRETR(user, param); break; // 处理上传文件命令 case \"STOR\": CommandSTOR(user, param); break; // 处理删除命令 case \"DELE\": CommandDELE(user, param); break; // 使用Type命令在ASCII和二进制模式进行变换 case \"TYPE\": CommandTYPE(user, param); break; default: sendString = \"502 command is not implemented.\"; )))))) RepleyCommandToUser(user, sendString); break; } break; } } } } // 想客户端返回响应码 private void RepleyCommandToUser(User user, string str) { try { user.commandSession.streamWriter.WriteLine(str); AddInfo(string.Format(\"向客户端({0})发送[{1}]\user.commandSession.tcpClient.Client.RemoteEndPoint, )))))) str)); } catch { AddInfo(string.Format(\"向客户端({0})发送信息失败\user.commandSession.tcpClient.Client.RemoteEndPoint)); } } // 向屏幕输出显示状态信息(这里使用了委托机制) private delegate void AddInfoDelegate(string str); private void AddInfo(string str) { // 如果调用AddInfo()方法的线程与创建ListView控件的线程不在一个线程时 // 此时利用委托在创建ListView的线程上调用 if (lstboxStatus.InvokeRequired == true) { AddInfoDelegate d = new AddInfoDelegate(AddInfo); )))))) this.Invoke(d, str); } else { lstboxStatus.Items.Add(str); lstboxStatus.TopIndex = lstboxStatus.Items.Count - 1; lstboxStatus.ClearSelected(); } } #region 处理各个命令 #region 登录过程,即用户身份验证过程 // 处理USER命令,接收用户名但不进行验证 private void CommandUser(User user, string command, string param) { string sendString = string.Empty; if (command == \"USER\") { sendString = \"331 USER command OK, password )))))) required.\"; user.userName = param; // 设置loginOk=1为了确保后面紧接的要求输入密码 // 1表示已接收到用户名,等到接收密码 user.loginOK = 1; } else { sendString = \"501 USER command syntax error.\"; } RepleyCommandToUser(user, sendString); } // 处理PASS命令,验证用户名和密码 private void CommandPassword(User user, string command, string param) { string sendString = string.Empty; if (command == \"PASS\") )))))) { string password = null; if (users.TryGetValue(user.userName, out password)) { if (password == param) { sendString = \"230 User logged in success\"; // 2表示登录成功 user.loginOK = 2; } else { sendString = \"530 Password incorrect.\"; } } else { sendString = \"530 User name or password incorrect.\"; )))))) } } else { sendString = \"501 PASS command Syntax error.\"; } RepleyCommandToUser(user, sendString); // 用户当前工作目录 user.currentDir = user.workDir; } #endregion #region 文件管理命令 // 处理CWD命令,改变工作目录 private void CommandCWD(User user, string temp) { string sendString = string.Empty; try { )))))) string dir = user.workDir.TrimEnd('/') + temp; // 是否为当前目录的子目录,且不包含父目录名称 if (Directory.Exists(dir)) { user.currentDir = dir; sendString = \"250 Directory changed to '\" + dir + \"' successfully\"; } else { sendString = \"550 Directory '\" + dir + \"' does not exist\"; } } catch { sendString = \"502 Directory changed unsuccessfully\"; } )))))) RepleyCommandToUser(user,sendString); } // 处理PWD命令,显示工作目录 private void CommandPWD(User user) { string sendString = string.Empty; sendString = \"257 '\" + user.currentDir + \"' is the current directory\"; RepleyCommandToUser(user, sendString); } // 处理LIST/NLIST命令,想客户端发送当前或指定目录下的所有文件名和子目录名 private void CommandLIST(User user, string parameter) { string sendString = string.Empty; DateTimeFormatInfo dateTimeFormat = new CultureInfo(\"en-US\ )))))) // 得到目录列表 string[] dir = Directory.GetDirectories(user.currentDir); if (string.IsNullOrEmpty(parameter) == false) { if (Directory.Exists(user.currentDir + parameter)) { dir = Directory.GetDirectories(user.currentDir + parameter); } else { string s = user.currentDir.TrimEnd('/'); user.currentDir = s.Substring(0, s.LastIndexOf(\"/\") + 1); } } for (int i = 0; i < dir.Length; i++) { string folderName = )))))) Path.GetFileName(dir[i]); DirectoryInfo d = new DirectoryInfo(dir[i]); // 按下面的格式输出目录列表 sendString += @\"dwr-\\" + Dns.GetHostName() + \"\\" + dateTimeFormat.GetAbbreviatedMonthName(d.CreationTime.Month) + d.CreationTime.ToString(\" dd yyyy\") + \"\\" + folderName + Environment.NewLine; } // 得到文件列表 string[] files = Directory.GetFiles(user.currentDir); if (string.IsNullOrEmpty(parameter) == false) { if (Directory.Exists(user.currentDir + parameter + \"/\")) { files = )))))) Directory.GetFiles(user.currentDir + parameter + \"/\"); } } for (int i = 0; i < files.Length; i++) { FileInfo f = new FileInfo(files[i]); string fileName = Path.GetFileName(files[i]); // 按下面的格式输出文件列表 sendString += \"-wr-\\" + Dns.GetHostName() + \"\\" + f.Length + \" \" + dateTimeFormat.GetAbbreviatedMonthName(f.CreationTime.Month) + f.CreationTime.ToString(\" dd yyyy\") + \"\\" + fileName + Environment.NewLine; } // List命令指示获得FTP服务器上的文件列表字符串信息 // 所以调用List命令过程,客户端接受的指示一些字符串 )))))) // 所以isBinary是false,代表传输的是ASCII数据 // 但是为了防止isBinary因为 设置user.isBinary = false而改变 // 所以事先保存user.IsBinary的引用(此时为true),方便后面下载文件 bool isBinary = user.isBinary; user.isBinary = false; RepleyCommandToUser(user, \"150 Opening ASCII data connection\"); InitDataSession(user); SendByUserSession(user, sendString); RepleyCommandToUser(user, \"226 Transfer complete\"); user.isBinary = isBinary; } // 处理RETR命令,提供下载功能,将用户请求的文件发送给用户 private void CommandRETR(User user, string filename) { )))))) string sendString = \"\"; // 下载的文件全名 string path = user.currentDir + filename; FileStream filestream = new FileStream(path, FileMode.Open, FileAccess.Read); // 发送150到用户,表示服务器文件状态良好,将要打开数据连接传输文件 if (user.isBinary) { sendString = \"150 Opening BINARY mode data connection for download\"; } else { sendString = \"150 Opening ASCII mode data connection for download\"; } RepleyCommandToUser(user, sendString); InitDataSession(user); )))))) SendFileByUserSession(user, filestream); RepleyCommandToUser(user, \"226 Transfer complete\"); } // 处理STOR命令,提供上传功能,接收客户端上传的文件 private void CommandSTOR(User user, string filename) { string sendString = \"\"; // 上传的文件全名 string path = user.currentDir + filename; FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); // 发送150到用户,表示服务器状态良好 if (user.isBinary) { sendString = \"150 Opening BINARY mode data connection for upload\"; } )))))) else { sendString = \"150 Opeing ASCII mode data connection for upload\"; } RepleyCommandToUser(user, sendString); InitDataSession(user); ReadFileByUserSession(user, fs); RepleyCommandToUser(user,\"226 Transfer complete\"); } // 处理DELE命令,提供删除功能,删除服务器上的文件 private void CommandDELE(User user, string filename) { string sendString = \"\"; // 删除的文件全名 string path = user.currentDir + filename; AddInfo(\"正在删除文件\" + filename + \"...\"); )))))) File.Delete(path); AddInfo(\"删除成功\"); sendString = \"250 File \" + filename + \" has been deleted.\"; RepleyCommandToUser(user, sendString); } #endregion #region 模式设置命令 // 处理PASV命令, 使用被动模式进行传输 private void CommandPASV(User user) { string sendString = string.Empty; IPAddress localip = Dns.GetHostEntry(\"\").AddressList[1]; // 被动模式,即服务器接收客户端的连接请求 // 被动模式下FTP服务器使用随机生成的端口进行传输数据 // 而主动模式下FTP服务器使用端口20进行数据传)))))) 输 Random random = new Random(); int random1, random2; int port; while (true) { // 随机生成一个端口进行数据传输 random1 = random.Next(5, 200); random2 = random.Next(0, 200); // 生成的端口号控制>1024的随机端口 // 下面这个运算算法只是为了得到一个大于1024的端口值 port = random1 << 8 | random2; try { user.dataListener = new TcpListener(localip, port); AddInfo(\"TCP 数据连接已打开(被动模式)--\" + localip.ToString() + \":\" + port); } catch { )))))) continue; } user.isPassive = true; string temp = localip.ToString().Replace('.', ','); // 必须把端口号IP地址告诉客户端,客户端接收到响应命令后, // 再通过新的端口连接服务器的端口P,然后进行文件数据传输 sendString = \"227 Entering Passive Mode(\" + temp + \ RepleyCommandToUser(user, sendString); user.dataListener.Start(); break; } } // 处理PORT命令,使用主动模式进行传输 private void CommandPORT(User user, string portstring) )))))) { // 主动模式时,客户端必须告知服务器接收数据的端口号,PORT 命令格式为:PORT address // address参数的格式为i1、i2、i3、i4、p1、p2,其中i1、i2、i3、i4表示IP地址 // 下面通过.字符串来组合这四个参数得到IP地址 // p1、p2表示端口号,下面通过int.Parse(temp[4]) << 8) | int.Parse(temp[5] // 这个算法来获得一个大于1024的端口来发送给服务器 string sendString = string.Empty; string[] temp = portstring.Split(','); string ipString = \"\" + temp[0] + \".\" + temp[1] + \".\" + temp[2] + \".\" + temp[3]; // 客户端发出PORT命令把客户端的IP地址和随机的端口告诉服务器 int portNum = (int.Parse(temp[4]) << 8) | int.Parse(temp[5]); user.remoteEndPoint = new IPEndPoint(IPAddress.Parse(ipString), portNum); sendString = \"200 PORT command successful.\"; )))))) // 服务器以接受到的客户端IP地址和端口为目标发起主动连接请求 // 服务器根据客户端发送过来的IP地址和端口主动发起与客户端建立连接 RepleyCommandToUser(user, sendString); } // 处理TYPE命令,设置数据传输方式 private void CommandTYPE(User user, string param) { string sendstring = \"\"; if (param == \"I\") { // 二进制 user.isBinary = true; sendstring = \"220 Type set to I(Binary)\"; } else { // ASCII方式 user.isBinary = false; )))))) sendstring = \"330 Type set to A(ASCII)\"; } RepleyCommandToUser(user, sendstring); } #endregion #endregion // 初始化数据连接 private void InitDataSession(User user) { TcpClient client = null; if (user.isPassive) { AddInfo(\"采用被动模式返回LIST目录和文件列表\"); client = user.dataListener.AcceptTcpClient(); } else )))))) { AddInfo(\"采用主动模式向用户发送LIST目录和文件列表\"); client = new TcpClient(); client.Connect(user.remoteEndPoint); } user.dataSession = new UserSeesion(client); } // 使用数据连接发送字符串 private void SendByUserSession(User user, string sendString) { AddInfo(\"向用户发送(字符串信息):[\" + sendString + \"]\"); try { user.dataSession.streamWriter.WriteLine(sendString); AddInfo(\"发送完毕\"); } )))))) finally { user.dataSession.Close(); } } // 使用数据连接发送文件流(客户端发送下载文件命令) private void SendFileByUserSession(User user, FileStream fs) { AddInfo(\"向用户发送(文件流):[...\"); try { if (user.isBinary) { byte[] bytes = new byte[1024]; BinaryReader binaryReader = new BinaryReader(fs); int count = binaryReader.Read(bytes, 0, bytes.Length); while (count > 0) )))))) { user.dataSession.binaryWriter.Write(bytes, 0, count); user.dataSession.binaryWriter.Flush(); count = binaryReader.Read(bytes, 0, bytes.Length); } } else { StreamReader streamReader = new StreamReader(fs); while (streamReader.Peek() > -1) { user.dataSession.streamWriter.WriteLine(streamReader.ReadLine()); } } AddInfo(\"...]发送完毕!\"); )))))) } finally { user.dataSession.Close(); fs.Close(); } } // 使用数据连接接收文件流(客户端发送上传文件功能) private void ReadFileByUserSession(User user, FileStream fs) { AddInfo(\"接收用户上传数据(文件流):[...\"); try { if (user.isBinary) { byte[] bytes = new byte[1024]; BinaryWriter binaryWriter = new BinaryWriter(fs); int count = )))))) user.dataSession.binaryReader.Read(bytes, 0, bytes.Length); while (count > 0) { binaryWriter.Write(bytes, 0, count); binaryWriter.Flush(); count = user.dataSession.binaryReader.Read(bytes, 0, bytes.Length); } } else { StreamWriter streamWriter = new StreamWriter(fs); while (user.dataSession.streamReader.Peek() > -1) { streamWriter.Write(user.dataSession.streamReader.ReadLine()); )))))) streamWriter.Flush(); } } AddInfo(\"...]接收完毕\"); } finally { user.dataSession.Close(); fs.Close(); } } } } ////////////////////////////////////////////////////////////////////////////// //User类: // 添加额外的引用 using System.Net; using System.Net.Sockets; )))))) namespace FtpServer { ///

/// 保存与客户端通信需要的信息 /// class User { public UserSeesion commandSession { get; set; } public UserSeesion dataSession { get; set; } public TcpListener dataListener { get; set; } // 主动模式下使用的客户端监听的IPEndPoint public IPEndPoint remoteEndPoint { get; set; } // 用户名 public string userName { get; set; } // 工作目录 public string workDir { get; set; } // 当前工作目录 public string currentDir { get; set; } )))))) // 初始状态为等待输入用户名 public int loginOK { get; set; } // 是否使用二进制数据传输方式 public bool isBinary { get; set; } // 数据连接使用的是否被动连接 public bool isPassive { get; set; } } } ////////////////////////////////////////////////////////////////////////////// //UserSession类: using System.IO; using System.Net.Sockets; using System.Text; namespace FtpServer { /// /// 保存连接设置信息 )))))) /// public class UserSeesion { private NetworkStream networkStream; public readonly StreamReader streamReader; public readonly StreamWriter streamWriter; // TcpClient对象代表一个客户端对象 public readonly TcpClient tcpClient; public readonly BinaryReader binaryReader; public readonly BinaryWriter binaryWriter; public UserSeesion(TcpClient client) { this.tcpClient = client; networkStream = client.GetStream(); streamReader = new StreamReader(networkStream, Encoding.Default); streamWriter = new StreamWriter(networkStream, Encoding.Default); streamWriter.AutoFlush = true; binaryReader = new BinaryReader(networkStream, Encoding.Default); binaryWriter = new )))))) BinaryWriter(networkStream, Encoding.Default); } public void Close() { tcpClient.Client.Shutdown(SocketShutdown.Both); tcpClient.Client.Close(); tcpClient.Close(); } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 上传下载器核心代码 ////////////////////////////////////////////////////////////////////////////////// using System; using System.IO; using System.Net; using System.Text; )))))) using System.Windows.Forms; namespace FTPUPDownloaderDome { public partial class FTPForm : Form { private const int FTPPORT = 21; private string _ftpUristring = null; private NetworkCredential _networkCredential; private string _currentDir = \"/\"; public FTPForm() { InitializeComponent(); IPAddress[] ips = Dns.GetHostAddresses(\"\"); txtFTPServer.Text = ips[2].ToString(); txtFTPServer.SelectAll(); btnLogin.Enabled = true; lstboxFTPResource.Enabled = false; lstboxFTPState.Enabled = false; btnUpload.Enabled = false; btnDownload.Enabled = false; )))))) btnDel.Enabled = false; } #region 键盘按下事件 private void txtUserName_KeyPress(object sender, KeyPressEventArgs e) { //输入用户名回车后,焦点直接转到密码文本框 if (e.KeyChar == (char)13) { txtPW.Focus(); } } private void txtFTPServer_KeyPress(object sender, KeyPressEventArgs e) { //输入服务器地址回车后,焦点直接转到用户名文本框 if (e.KeyChar == (char)13) { txtUserName.Focus(); } )))))) } private void txtPW_KeyPress(object sender, KeyPressEventArgs e) { //输入密码回车后直接可以登录 if (e.KeyChar == (char)13) { btnLogin.Focus(); } } #endregion /// /// 匿名 /// /// /// private void chkAnonymity_Click(object sender, EventArgs e) { //实名方式登陆 if (!chkAnonymity.Checked) )))))) { txtUserName.Enabled = true; txtUserName.Text = \"user1\"; txtPW.Enabled = true; txtPW.Text = \"\"; txtUserName.Focus(); } //匿名方式 else { txtUserName.Text = \"anonymous\"; txtUserName.Enabled = false; txtPW.Text = \"\"; txtPW.Enabled = false; } } #region 与服务器的交互 /// /// 创建FTP连接 /// /// )))))) /// /// private FtpWebRequest CreateFTPWebRequest(string uri, string requestMethod) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(uri); request.Credentials = _networkCredential; request.KeepAlive = true; request.UseBinary = true; request.Method = requestMethod; return request; } /// /// 获取FTP服务器的响应 /// /// /// private FtpWebResponse GetFTPWebResponse(FtpWebRequest request) { try )))))) { FtpWebResponse response = (FtpWebResponse)request.GetResponse(); lstboxFTPState.Items.Add(\"验证完毕,服务器回应信息:[\" + response.WelcomeMessage + \"]\"); lstboxFTPState.Items.Add(\"正在连接:[ \" + response.BannerMessage + \"]\"); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; return response; } catch (WebException ex) { lstboxFTPState.Items.Add(\"发送错误。返回信息为:\" + ex.Status); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; return null; } } #endregion )))))) #region 登陆模块的实现 /// /// 登陆 /// /// /// private void btnLogin_Click(object sender, EventArgs e) { if (txtFTPServer.Text == string.Empty) { MessageBox.Show(\"请先填写服务器IP地址\\"提示\"); return; } _ftpUristring = \"ftp://\" + txtFTPServer.Text; _networkCredential = new NetworkCredential(txtUserName.Text, txtPW.Text); if (ShowFtpFileAndDirectory() == true) { btnLogin.Enabled = false; btnLogout.Enabled = true; )))))) lstboxFTPResource.Enabled = true; lstboxFTPState.Enabled = true; txtFTPServer.Enabled = false; if (!chkAnonymity.Checked) { txtUserName.Enabled = false; txtPW.Enabled = false; chkAnonymity.Enabled = false; } else { chkAnonymity.Enabled = false; } txtLoginMessage.Text = \"登录成功\"; btnUpload.Enabled = true; btnDownload.Enabled = true; btnDel.Enabled = true; } else { lstboxFTPState.Enabled = true; txtLoginMessage.Text = \"登录失败\"; )))))) } } /// /// 显示资源列表 /// /// private bool ShowFtpFileAndDirectory() { lstboxFTPResource.Items.Clear(); string uri = string.Empty; if (_currentDir == \"/\") { uri = _ftpUristring; } else { uri = _ftpUristring + _currentDir; } string[] urifield = uri.Split(' '); uri = urifield[0]; FtpWebRequest request = )))))) CreateFtpWebRequest(uri, WebRequestMethods.Ftp.ListDirectoryDetails); // 获得服务器返回的响应信息 FtpWebResponse response = GetFTPWebResponse(request); if (response == null) { return false; } lstboxFTPState.Items.Add(\"连接成功,服务器返回的是:\" + response.StatusCode + \" \" + response.StatusDescription); // 读取网络流数据 Stream stream = response.GetResponseStream(); StreamReader streamReader = new StreamReader(stream, Encoding.Default); lstboxFTPState.Items.Add(\"获取响应流....\"); string s = streamReader.ReadToEnd(); streamReader.Close(); stream.Close(); response.Close(); lstboxFTPState.Items.Add(\"传输完成\"); )))))) // 处理并显示文件目录列表 string[] ftpdir = s.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); lstboxFTPResource.Items.Add(\"↑返回上层目录\"); int length = 0; for (int i = 0; i < ftpdir.Length; i++) { if (ftpdir[i].EndsWith(\".\")) { length = ftpdir[i].Length - 2; break; } } for (int i = 0; i < ftpdir.Length; i++) { s = ftpdir[i]; int index = s.LastIndexOf('\'); if (index == -1) { )))))) if (length < s.Length) { index = length; } else { continue; } } string name = s.Substring(index + 1); if (name == \".\" || name == \"..\") { continue; } // 判断是否为目录,在名称前加\"目录\"来表示 if (s[0] == 'd' || (s.ToLower()).Contains(\"\")) { string[] namefield = name.Split(' '); int namefieldlength = )))))) namefield.Length; string dirname; dirname = namefield[namefieldlength - 1]; // 对齐 dirname = dirname.PadRight(34, ' '); name = dirname; // 显示目录 lstboxFTPResource.Items.Add(\"[目录]\" + name); } } for (int i = 0; i < ftpdir.Length; i++) { s = ftpdir[i]; int index = s.LastIndexOf('\'); if (index == -1) { if (length < s.Length) { )))))) index = length; } else { continue; } } string name = s.Substring(index + 1); if (name == \".\" || name == \"..\") { continue; } // 判断是否为文件 if (!(s[0] == 'd' || (s.ToLower()).Contains(\"\"))) { string[] namefield = name.Split(' '); int namefieldlength = namefield.Length; string filename; )))))) filename = namefield[namefieldlength - 1]; // 对齐 filename = filename.PadRight(34, ' '); name = filename; // 显示文件 lstboxFTPResource.Items.Add(name); } } return true; } private FtpWebRequest CreateFtpWebRequest(string uri, string requestMethod) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(uri); request.Credentials = _networkCredential; request.KeepAlive = true; request.UseBinary = true; )))))) request.Method = requestMethod; return request; } /// /// 注销 /// /// /// private void btnLogout_Click(object sender, EventArgs e) { btnLogin.Enabled = true; btnLogout.Enabled = false; txtFTPServer.Enabled = true; txtFTPServer.SelectAll(); txtFTPServer.Focus(); chkAnonymity.Enabled = true; if (!chkAnonymity.Checked) { txtUserName.Enabled = true; txtPW.Enabled = true; } )))))) txtLoginMessage.Text = \"你已经退出了。\"; lstboxFTPResource.Items.Clear(); lstboxFTPResource.Enabled = false; lstboxFTPState.Items.Clear(); lstboxFTPState.Enabled = false; btnUpload.Enabled = false; btnDownload.Enabled = false; btnDel.Enabled = false; } #endregion #region 对文件的操作模块实现 /// /// 上传文件到服务器 /// /// /// private void btnUpload_Click(object sender, EventArgs e) { // 选择要上传的文件 OpenFileDialog openFileDialog = new )))))) OpenFileDialog(); openFileDialog.FileName = openFileDialog.FileNames.ToString(); openFileDialog.Filter = \"所有文件(*.*)|*.*\"; if (openFileDialog.ShowDialog() != DialogResult.OK) { return; } FileInfo fileinfo = new FileInfo(openFileDialog.FileName); try { string uri = GetUriString(fileinfo.Name); FtpWebRequest request = CreateFTPWebRequest(uri, WebRequestMethods.Ftp.UploadFile); request.ContentLength = fileinfo.Length; int buflength = 8196; byte[] buffer = new byte[buflength]; FileStream filestream = )))))) fileinfo.OpenRead(); Stream responseStream = request.GetRequestStream(); lstboxFTPState.Items.Add(\"打开上传流,文件上传中...\"); int contenlength = filestream.Read(buffer, 0, buflength); while (contenlength != 0) { responseStream.Write(buffer, 0, contenlength); contenlength = filestream.Read(buffer, 0, buflength); } responseStream.Close(); filestream.Close(); FtpWebResponse response = GetFTPWebResponse(request); if (response == null) { lstboxFTPState.Items.Add(\"服务器未响)))))) 应...\"); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; return; } lstboxFTPState.Items.Add(\"上传完毕,服务器返回:\" + response.StatusCode + \" \" + response.StatusDescription); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; MessageBox.Show(\"上传成功!\"); // 上传成功后,立即刷新服务器目录列表 ShowFtpFileAndDirectory(); } catch (WebException ex) { lstboxFTPState.Items.Add(\"上传发生错误,返回信息为:\" + ex.Status); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; )))))) MessageBox.Show(ex.Message, \"上传失败\"); } } /// /// 从服务器上下载文件 /// /// /// private void btnDownload_Click(object sender, EventArgs e) { string fileName = GetSelectedFile(); if (fileName.Length == 0) { MessageBox.Show(\"请选择要下载的文件!\\"提示\"); return; } // 选择保存文件的位置 SaveFileDialog saveFileDialog = new )))))) SaveFileDialog(); saveFileDialog.FileName = fileName; saveFileDialog.Filter = \"所有文件(*.*)|(*.*)\"; if (saveFileDialog.ShowDialog() != DialogResult.OK) { return; } string filePath = saveFileDialog.FileName; try { string uri = GetUriString(fileName); FtpWebRequest request = CreateFTPWebRequest(uri, WebRequestMethods.Ftp.DownloadFile); FtpWebResponse response = GetFTPWebResponse(request); if (response == null) { lstboxFTPState.Items.Add(\"服务器未响)))))) 应...\"); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; return; } Stream responseStream = response.GetResponseStream(); FileStream filestream = File.Create(filePath); int buflength = 8196; byte[] buffer = new byte[buflength]; int bytesRead = 1; lstboxFTPState.Items.Add(\"打开下载通道,文件下载中...\"); while (bytesRead != 0) { bytesRead = responseStream.Read(buffer, 0, buflength); filestream.Write(buffer, 0, bytesRead); } )))))) responseStream.Close(); filestream.Close(); lstboxFTPState.Items.Add(\"下载完毕,服务器返回:\" + response.StatusCode + \" \" + response.StatusDescription); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; MessageBox.Show(\"下载完成!\"); } catch (WebException ex) { lstboxFTPState.Items.Add(\"发生错误,返回状态为:\" + ex.Status); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; MessageBox.Show(ex.Message, \"下载失败\"); } } /// )))))) /// 获取资源路径 /// /// 文件名 /// 资源路径 private string GetUriString(string filename) { string uri = string.Empty; if (_currentDir.EndsWith(\"/\")) { uri = _ftpUristring + _currentDir + filename; } else { uri = _ftpUristring + _currentDir + \"/\" + filename; } return uri; } /// /// 获得选择的文件 /// 如果选择的是目录或者是返回上层目录,)))))) 则返回null /// /// private string GetSelectedFile() { string filename = string.Empty; if (!(lstboxFTPResource.SelectedIndex == -1 || lstboxFTPResource.SelectedItem.ToString().Substring(0, 4) == \"[目录]\")) { string[] namefield = lstboxFTPResource.SelectedItem.ToString().Split(' '); filename = namefield[0]; } return filename; } /// /// 删除服务器上的文件 /// /// /// private void btnDel_Click(object sender, EventArgs )))))) e) { string filename = GetSelectedFile(); if (filename.Length == 0) { MessageBox.Show(\"请选择要删除的文件!\\"提示\"); return; } try { string uri = GetUriString(filename); if (MessageBox.Show(\"确定要删除文件 \" + filename + \" 吗?\确认文件删除\MessageBoxButtons.YesNo) == DialogResult.Yes) { FtpWebRequest request = CreateFTPWebRequest(uri, WebRequestMethods.Ftp.DeleteFile); FtpWebResponse response = GetFTPWebResponse(request); if (response == null) )))))) { lstboxFTPState.Items.Add(\"服务器未响应...\"); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; return; } lstboxFTPState.Items.Add(\"文件删除成功,服务器返回:\" + response.StatusCode + \" \" + response.StatusDescription); ShowFtpFileAndDirectory(); } else { return; } } catch (WebException ex) { lstboxFTPState.Items.Add(\"发生错误,返回)))))) 状态为:\" + ex.Status); lstboxFTPState.TopIndex = lstboxFTPState.Items.Count - 1; MessageBox.Show(ex.Message, \"删除失败\"); } } #endregion /// /// 变更目录操作 /// /// /// private void lstboxFTPResource_MouseDoubleClick(object sender, MouseEventArgs e) { // 点击返回上层目录 if (lstboxFTPResource.SelectedIndex == 0) { if (_currentDir == \"/\") { )))))) MessageBox.Show(\"当前目录已经是顶层目录\MessageBoxIcon.Exclamation); return; } int index = _currentDir.LastIndexOf(\"/\"); if (index == 0) { _currentDir = \"/\"; } else { _currentDir = _currentDir.Substring(0, index); } // 每次更改目录后立即刷新资源列表 ShowFtpFileAndDirectory(); } else { if (lstboxFTPResource.SelectedIndex > 0 && )))))) lstboxFTPResource.SelectedItem.ToString().Contains(\"[目录]\")) { if (_currentDir == \"/\") { _currentDir = \"/\" + lstboxFTPResource.SelectedItem.ToString().Substring(4); } else { _currentDir = _currentDir + \"/\" + lstboxFTPResource.SelectedItem.ToString().Substring(4); } string[] _currentDirfield = _currentDir.Split(' '); _currentDir = _currentDirfield[0]; // 每次更改目录后立即刷新资源列表 ShowFtpFileAndDirectory(); } } )))))) )))))))) } } } 启动服务器: 登陆链接: )))))) )))))))) )))))) )))))))) 实验通过实验掌握了C#中FTP上传下载器编程的方法。 总结 指导教师意见 签名: 年 月 日 ))))))

因篇幅问题不能全部显示,请点此查看更多更全内容