计算机网络课程设计报告-简单FTP服务器实现参考Word文档格式.docx
《计算机网络课程设计报告-简单FTP服务器实现参考Word文档格式.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计报告-简单FTP服务器实现参考Word文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
表1FTP协议应答码
应答码
意义
110
重新启动标记应答。
在这种情况下文本是确定的,它必须是:
MARKyyyy=mmmm,其中yyyy是用户进程数据流标记,mmmm是服务器标记。
120
服务在nnn分钟内准备好
125
数据连接已打开,准备传送
150
文件状态良好,打开数据连接
200
命令成功
202
命令未实现
211
系统状态或系统帮助响应
212
目录状态
213
文件状态
214
帮助信息,信息仅对人类用户有用
215
名字系统类型
220
对新用户服务准备好
221
服务关闭控制连接,可以退出登录
225
数据连接打开,无传输正在进行
226
关闭数据连接,请求的文件操作
227
进入被动模式
成功
230
用户登录
250
请求的文件操作完成
257
创建"
PATHNAME"
331
用户名正确,需要口令
332
登录时需要帐户信息
350
请求的文件操作需要进一步命令
421
不能提供服务,关闭控制连接
425
不能打开数据连接
426
关闭连接,中止传输
450
请求的文件操作未执行
451
中止请求的操作:
有本地错误
452
未执行请求的操作:
系统存储空间不足
500
格式错误,命令不可识别
501
参数语法错误
502
503
命令顺序错误
504
此参数下的命令功能未实现
530
未登录
532
存储文件需要帐户信息
550
未执行请求的操作
551
请求操作中止:
页类型未知
552
请求的文件操作中止,存储分配溢出
553
文件名不合法
1.2TCP协议的编程
Socket(套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。
可以将Socket看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。
Socket存在于通信域中,通信域是为了处理一般的线程通过Socket通信而引进的一种抽象概念。
Socket通常和同一个域中的Socket交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。
各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。
2功能设计
2.1功能示意图
客户端
下载
登陆
服务器端
链接
主动
验证登陆
上传
被动
删除
图2 实现功能示意图
以FTP的工作原理和权限归属为基础,用C#语言编写程序,,用简单界面
展示,用socket编程和二进制输入输出流来实现了FTP文件上传,下载,删除,读取文件列表这几项功能。
采用端口为21和IP地址为127.0.0.1连接。
3代码实现
3.1启动服务器(服务器端)
//启动服务器
privatevoidbtnFtpServerStartStop_Click(objectsender,EventArgse)
{
if(myTcpListener==null)
listenThread=newThread(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();
Ftp服务已停止!
"
lstboxStatus.TopIndex=lstboxStatus.Items.Count-1;
btnFtpServerStartStop.Text="
启动"
//使用数据连接发送文件流(客户端发送下载文件命令)
privatevoidSendFileByUserSession(Useruser,FileStreamfs)
AddInfo("
向用户发送(文件流):
[..."
try
if(user.isBinary)
byte[]bytes=newbyte[1024];
BinaryReaderbinaryReader=newBinaryReader(fs);
Intcount=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);
StreamReaderstreamReader=newStreamReader(fs);
while(streamReader.Peek()>
-1)
user.dataSession.streamWriter.WriteLine(streamReader.ReadLine());
...]发送完毕!
finally
user.dataSession.Close();
fs.Close();
3.2文件传输操作(客户端)
由于代码过多且相似,以显示文件目录和上传文件为例。
//处理并显示文件目录列表
string[] ftpdir = s.Split(Environment.NewLine.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
intlength=0;
for(inti=0;
i<
ftpdir.Length;
i++)
if(ftpdir[i].EndsWith("
."
))
{length=ftpdir[i].Length-2;
s=ftpdir[i];
intindex=s.LastIndexOf('
\t'
if(index==-1)
if(length<
s.Length)
{index=length;
}else
{continue;
stringname=s.Substring(index+1);
if(name=="
||name=="
.."
)
{continue;
//判断是否为目录,在名称前加"
目录"
来表示
if(s[0]=='
d'
||(s.ToLower()).Contains("
<
dir>
string[]namefield=name.Split('
'
intnamefieldlength=namefield.Length;
stringdirname;
dirname=namefield[namefieldlength-1];
//对齐
dirname=dirname.PadRight(34,'
name=dirname;
//显示目录
lstbxFtpResources.Items.Add("
[目录]"
+name);
//判断是否为文件
if(!
(s[0]=='
)))
stringfilename
filename=namefield[namefieldlength-1];
//上传文件到服务器事件
privatevoidbtnUpload_Click(objectsender,EventArgse)
//选择要上传的文件
OpenFileDialogopenFileDialog=newOpenFileDialog();
openFileDialog.FileName=openFileDialog.FileNames.ToString();
openFileDialog.Filter="
所有文件(*.*)|*.*"
if(openFileDialog.ShowDialog()!
=DialogResult.OK)
return;
FileInfofileinfo=newFileInfo(openFileDialog.FileName);
stringuri=GetUriString(fileinfo.Name);
FtpWebRequest request = CreateFtpWebRequest(uri,WebRequestMethods.Ftp.UploadFile);
request