资源描述
FTP 客户端 - 服务器端编程 目录服务端设计 . 1 相关代码 . 4客户端设计 . 16 相关代码 . 18程序结果 . 26总结 .27服务端 相关类图 using System;using System.Collections.Generic;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;using System.Globalization;namespace FtpServerExample public partial class MainForm : Form TcpListener myTcpListener; Dictionary users; /保存用户名和密码 public MainForm() InitializeComponent(); users = new Dictionary(); users.Add(mytestName, 12345); /初始帐号 密码 textBox1.Text = G:/download; /设置默认主目录 / 单击【启动FTP服务】触发的事件 private void buttonStart_Click(object sender, EventArgs e) this.listBoxStatus.Items.Add(FTP服务已启动); Thread t = new Thread(ListenClientConnect); t.IsBackground = true; t.Start(); buttonStart.Enabled = false; buttonStop.Enabled = true; / 监听端口,处理客户端连接 private void ListenClientConnect() myTcpListener = new TcpListener(IPAddress.Any, 21); myTcpListener.Start(); while (true) try TcpClient client = myTcpListener.AcceptTcpClient(); AddInfo(string.Format(0和本机(1)建立FTP连接, client.Client.RemoteEndPoint, myTcpListener.LocalEndpoint); User user = new User(); mandSession = new UserSession(client); user.workDir = textBox1.Text; Thread t = new Thread(UserProcessing); t.IsBackground = true; t.Start(user); catch break; / / 处理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; user.LoginOK = 1; /1表示已接收到用户名,等待接收密码 else sendString = 501 USER command syntax error.; ReplyCommandToUser(user, sendString); / / 处理密码命令,验证用户名和密码 / 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; user.LoginOK = 2; /2表示登录成功 else sendString = 530 Password incorrect.; else sendString = 530 User name or password incorrect.; else sendString = 501 PASS command Syntax error.; ReplyCommandToUser(user, sendString); user.CurrentDir = user.workDir; /用户当前工作目录 / 处理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; ReplyCommandToUser(user, sendString); private String AddEnd(String s) if (!s.EndsWith(/) s += /; return s; / 处理PWD命令,显示工作目 private void CommandPWD(User user) string sendString = string.Empty; sendString = 257 + user.CurrentDir + is the current directory; ReplyCommandToUser(user, sendString); / 处理PASV命令,设置数据传输模式 private void CommandPASV(User user) string sendString = string.Empty; IPAddress localIP = Dns.GetHostEntry(Dns.GetHostName().AddressList1; /被动模式 Random random = new Random(); int randNum1, randNum2, port; while (true) randNum1 = random.Next(5, 200); randNum2 = random.Next(0, 200); port = (randNum1 8) | randNum2; try user.dataListener = new TcpListener(localIP, port); AddInfo(被动模式- + localIP.ToString() + : + port); catch continue; user.isPassive = true; string tmp = localIP.ToString().Replace(., ,); sendString = 227 Entering Passive Mode ( + tmp + , + randNum1 + , + randNum2 + ); ReplyCommandToUser(user, sendString); user.dataListener.Start(); break; / 处理PORT命令,使用主动模式进行传输,获取客户端发过来的数据连接ip及端口信息 private void CommandPORT(User user, string portString) string sendString = string.Empty; String tmp = portString.Split(,); String ipString = + tmp0 + . + tmp1 + . + tmp2 + . + tmp3; int portNum = (int.Parse(tmp4) 8) | int.Parse(tmp5); user.remoteEndPoint = new IPEndPoint(IPAddress.Parse(ipString), portNum); sendString = 200 PORT command successful.; ReplyCommandToUser(user, sendString); / 处理LIST命令,向客户端发送当前或指定工作目录下的所有文件名和子目录名 private void CommandLIST(User user, string parameter) string sendString = string.Empty; DateTimeFormatInfo m = new CultureInfo(en-US, true).DateTimeFormat; /得到目录列表 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(diri); DirectoryInfo d = new DirectoryInfo(diri); sendString += dwr-t + Dns.GetHostName() + t + m.GetAbbreviatedMonthName(d.CreationTime.Month) + d.CreationTime.ToString( dd yyyy) + t + 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 0) bw.Write(bytes, 0, count); bw.Flush(); count = user.dataSession.br.Read(bytes, 0, bytes.Length); else StreamWriter sw = new StreamWriter(fs); while (user.dataSession.sr.Peek() -1) sw.WriteLine(user.dataSession.sr.ReadLine(); sw.Flush(); AddInfo(接收完毕); finally user.dataSession.Close(); fs.Close(); / 使用数据连接发送文件流 private void SendFileByUserSession(User user, FileStream fs) AddInfo(开始发送文件流); try if (user.isBinary) byte bytes = new byte1024; BinaryReader br = new BinaryReader(fs); int count = br.Read(bytes, 0, bytes.Length); while (count 0) user.dataSession.bw.Write(bytes, 0, count); user.dataSession.bw.Flush(); count = br.Read(bytes, 0, bytes.Length); else StreamReader sr = new StreamReader(fs); while (sr.Peek() -1) user.dataSession.sw.WriteLine(sr.ReadLine(); AddInfo(发送完毕); finally user.dataSession.Close(); fs.Close(); / 向客户端用户发送响应码信息 private void ReplyCommandToUser(User user, string str) try mandSession.sw.WriteLine(str); AddInfo(string.Format(向0发送:1, mandSession.client.Client.RemoteEndPoint, str); catch AddInfo(string.Format(向0发送信息失败, mandSession.client.Client.RemoteEndPoi
展开阅读全文