slide1 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
C# 网络编程技术教程 PowerPoint Presentation
Download Presentation
C# 网络编程技术教程

Loading in 2 Seconds...

play fullscreen
1 / 29

C# 网络编程技术教程 - PowerPoint PPT Presentation


  • 137 Views
  • Uploaded on

C# 网络编程技术教程. 第七章 FTP 编程. 学习目标. 了解 FTP 的相关基础知识。 掌握 .NET 中 FTP 的服务器端编程方法。 掌握 .NET 中 FTP 的客户端编程方法。. 本章内容. 7.1 FTP 概述 7.2 .NET 中的 FTP 编程. 7.1 FTP 概述.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'C# 网络编程技术教程' - mervyn


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
slide1

C#网络编程技术教程

第七章 FTP编程

slide2
学习目标
  • 了解FTP的相关基础知识。
  • 掌握.NET中FTP的服务器端编程方法。
  • 掌握.NET中FTP的客户端编程方法。
slide3
本章内容

7.1 FTP概述

7.2 .NET中的FTP编程

7 1 ftp
7.1 FTP概述

FTP(File Transfer Protocol,文件传输协议)是Internet中相当重要的应用之一。通过FTP,用户可从FTP服务器下载(Download)或上传(Upload)文件。FTP被整合在浏览器中,用户可利用浏览器通过超链接(Hyperlink),下载服务器开放的任意文件,达到资源共享的目的。

FTP是一种Client/Server体系结构,但与一般的Client/Server体系结构不同。与Socket网络程序应用的最大差别,在于其定义了服务器端与客户端的行为模式,即相关的指令、响应及传输的数据类型。因此在开发FTP应用程序时,应先了解FTP的详细内容。

FTP是由RFC959 File Transfer Protocol(FTP)所定义的。在此RFC中,强调了FTP的目的为:

 文件共享。

 通过应用程序直接或间接使用远程主机。

 提供一致性的协议,避免用户在不同主机上产生不同的操作方式。

 提供可靠及有效率的数据传输。

7 1 ftp1
7.1 FTP概述

7.1.1 FTP结构

一般的Client/Server应用程序,只会在服务器端与客户端建立一个Socket连接,此连接同时处理服务器端与客户端间的连接以及数据的传输。而FTP则不同,服务器与客户端之间共建立两个Socket连接,一个以FTP默认端口21作为两者间的通信连接,另一个则用于客户端传输指令与服务器响应结果。FTP服务器端分为Protocol Interpreter(PI)及Data Transfer Process(DTP)两个模块。服务器端PI用来建立服务器Socket以监听并接收处理FTP客户端的连接请求,此连接会一直持续至客户端结束FTP应用程序为止。

FTP服务器端DTP专门处理FTP协议所定义的特殊指令,并将执行结果或信息返回至客户端。因此,DTP主要是负责传输数据(包括文件)。

FTP客户端分为Protocol Interpreter(PI)、Data Transfer Process(DTP)及User Interface(UI)三个模块。FTP客户端PI用来与服务器建立连接。FTP客户端DTP用来将用户输入的FTP指令传输至服务器端处理,并且接收服务器端的响应(包括文件的处理)。FTP客户端UI用来提供用户与PI间的交互界面。

7 1 ftp2
7.1 FTP概述

7.1.2 FTP命令

除上述连接方式的特殊之外,FTP在命令与响应信息上也有其特殊的定义方式。FTP命令主要包括:访问命令、文件管理命令、数据格式命令、端口定义命令、文件传输命令和杂项命令。这些命令格式及描述分别见表7.1至表7.6所示。

7 1 ftp3
7.1 FTP概述

7.1.2 FTP命令

7 1 ftp4
7.1 FTP概述

7.1.2 FTP命令

7 1 ftp5
7.1 FTP概述

7.1.2 FTP命令

7 1 ftp6
7.1 FTP概述

7.1.3 FTP服务器响应码

RFC959对于FTP指令均明确定义其对应的FTP服务器响应信息,也称FTP服务器响应码,常用的FTP服务器响应码如表7.7所示。响应码由3位数字组成。其中第一位与第二位数字有其特殊的意义,分别如表7.8和表7.9所示。

7 1 ftp7
7.1 FTP概述

7.1.3 FTP服务器响应码

7 1 ftp8
7.1 FTP概述

7.1.3 FTP服务器响应码

7 1 ftp9
7.1 FTP概述

7.1.3 FTP流程

FTP流程是指在FTP协议的基础上,客户端与服务器端完成一次完整的数据信息传输(文件下载或上传)的过程。FTP流程通常由以下三个部分构成。

(1)用户身份确认。

(2)数据传输。

(3)结束FTP。

下面以下载文件操作为例,详细说明上述三个部分的处理流程。

1.用户身份确认

如图7.2所示。首先,FTP客户端尝试与FTP服务器建立连接。命令格式如下。

C:\>ftp localhost

若成功,服务器发回响应成功信息。信息格式如下。 Connected to localhost.

220 FTP Server - <version 1.0> - ready.

同时服务器要求用户输入登录账号。格式如下。 User (localhost: (none)):

用户输入账号并按下Enter键后,客户端则传输“USER<username>”的信息至FTP服务器,此时服务器将再次发回响应信息,同时提示用户输入密码。格式如下:

331 Password required for<username>

Password:

7 1 ftp10
7.1 FTP概述

7.1.4 FTP流程

其中<username>为用户刚刚输入的账号。如:User (localhost: (none)):jh

331 Password required for jh

Password:

用户输入密码并按下Enter键,客户端则传输“PASS<password>”信息至FTP服务器,并进行用户确认,若正确,服务器发回响应信息。格式如下。

230 User leo logged in.

ftp>

至此,完成用户确认的流程。

7 1 ftp11
7.1 FTP概述

7.1.4 FTP流程

2.数据传输

如图7.3所示,登录成功后,用户便可以输入相关的FTP指令至服务器。

例如要从FTP服务器下载文件download.txt。用户应在FTP提示符下输入下载命令,格式如下:

ftp> download.txt

客户端首先会传输PORT h1,h2,h3,h4,p1,p2至服务器,以便以此IP地址及端口与服务器端建立DTP数据传输的连接;如果连接成功,服务器发回响应信息,格式如下:

PORT 127,0,0,1,4,69

200 PORT command successful.

同时客户端会由DTP自动传输RETR download.txt指令至服务器,以便下载文件。当服务器端开始传输文件时,服务器会发回响应信息,格式如下:

150 Opening BINARY mode data connection for download.txt.

当下载成功后,服务器则发回如下信息:

226 Closing data connection. Transfer Complete.

ftp: 15bytes received in 0.00Seconds 15000.00Kbytes/sec.

至此,数据传输结束。

7 1 ftp12
7.1 FTP概述

7.1.4 FTP流程

3.结束FTP

流程如图7.4所示。当数据传输结束后,如不需要再进行其他文件传输,则FTP客户端发送QUIT命令,要求结束FTP连接。FTP服务器端则发回响应信息,表示结束连接。示例如下:

ftp> quit

221 Server closing control connection. Goodbye.

图7.3数据传输流程 图7.4结束FTP流程

7 2 net ftp
7.2 .NET中的FTP编程

文件传输系统服务器端和客户端的流程是:服务器端首先进行TCP监听,当有客户端连接请求时,将文件目录发送过去,客户端选择文件后,服务器构造一个文件流读取指定文件,然后将文件流赋给网络流发送到客户端,客户端接到网络流后,转化为文件流存放到文件。

7.2.1 数据发送和接收编程方法

1.数据发送编程方法

(1)当客户端输入了put命令后,会执行以下的代码向FTP服务器发送STOR命令,然后再通过sendData( )方法发送文件数据。如果接收成功,会收到226响应代码。要发送的文件数据通过readFileData( )方法读取。

(2)要发送的文件的数据通过readFileData( )方法获得,参数filename是要读取数据的文件名,返回值是从文件中读取的字节数据。

(3)获得文件数据后,通过sendData( )方法将其发送到FTP服务器。如果是PASV模式,就直接连接FTP服务器,然后发送数据;如果是PORT模式,就等待dataSocket为连接状态时发送。

2.数据接收编程方法

(1)当客户端输入了get命令后,会执行以下的代码从FTP服务器接收文件。如果接收成功,会收到了226响应代码,否则可能会收到550响应代码。接收文件数据通过receiveData( )函数完成,如果接收数据正确,返回值为文件内容,否则返回空字符串。如果接收到文件数据,就调用saveFileData( )方法进行保存。

(2)接收到文件数据后,通过saveFileData( )方法把数据写入文件中:参数filename是要保存的文件名,参数data是要写入的数据。代码首先检查文件是否存在,如果不存在就创建一个新文件。

7 2 net ftp1
7.2 .NET中的FTP编程

7.2.2 服务器端开发

1.界面设计

如图7.5所示,在窗体上拖放3个Label控件、1个TextBox控件、3个Button控件、2个RichTextBox控件、1个StatusBar控件。设置各个控件的属性如表7.10所示。

7 2 net ftp2
7.2 .NET中的FTP编程

7.2.2 服务器端开发

2.在代码窗口中添加引用

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.IO;

3.在代码窗口中添加私有成员

private bool control=false;

private int port;

private System.Net.Sockets.Socket sock;

private int number;

private int i;

private int j;

private System.Net.Sockets.TcpListener listener;

private System.Windows.Forms.StatusBarPanel statusBarPanel1;

private System.IO.FileStream filestream;

4.修改Form1构造方法

在Form1窗口中,单击鼠标右键选择“查看代码”,进入代码窗口。

public Form1( )

{

// Windows 窗体设计器支持所必需的

InitializeComponent( );

//

// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

string[ ] str=new string[1024];

for(int i=0;i<Directory.GetFiles("d:\\FTP虚拟目录").Length;i++)

{

str[i]=Directory.GetFiles("d:\\FTP虚拟目录")[i];

richTextBox1.AppendText(str[i]+"\r\n");

}

}

图7.5服务器端窗口

7 2 net ftp3
7.2 .NET中的FTP编程

7.2.2 服务器端开发

5.“开始服务”按钮的Click事件代码

private void button1_Click(object sender, System.EventArgs e)

{

try

{

port=Int32.Parse(textBox1.Text);

}

catch{MessageBox.Show("您输入的格式不对!请输入正整数。");}

try

{

listener=new TcpListener(port);

listener.Start( );

statusBarPanel1.Text="开始监听………";

Thread thread =new Thread(new ThreadStart(receive));

thread.Start( );

}

catch(Exception ex){MessageBox.Show(ex.Message);}

}

6.Receive( )方法代码

private void receive( )

{

sock=listener.AcceptSocket( );

if(sock.Connected)

{

statusBarPanel1.Text="与客户建立连接";

string str=richTextBox1.Text;

byte[] bytee=System.Text.Encoding.BigEndianUnicode.GetBytes(str.ToChar Array( ));

sock.Send(bytee,bytee.Length,0);

7 2 net ftp4
7.2 .NET中的FTP编程

7.2.2 服务器端开发

//接收信息

while(!control)

{

NetworkStream stream=new NetworkStream(sock);

byte[ ] by=new Byte[1024];

int i=sock.Receive(by,by.Length,0);

string ss=System.Text.Encoding.BigEndianUnicode.GetString(by);

richTextBox2.AppendText(ss);

j=richTextBox2.Lines.Length;

if(j>=2)

{

if(richTextBox2.Lines[j-2].ToString( )!="@@@@@@")

{//构造文件流

filestream=new

FileStream(richTextBox2.Lines[j-2].ToString( ),FileMode.Open,FileAccess.Read);

//定义缓冲区

byte[] b1=new byte[1024];

//循环读文件

while((number=filestream.Read(b1,0,1024))!=0)

{//向客户端发送流

stream.Write(b1,0,number);

//流刷新

stream.Flush( );

}

//文件发送结束,发送"<EOF>",提示客户文件传输完毕。

string st="<EOF>";

byte[] b2=new byte[1024];

byt=System.Text.Encoding.ASCII.GetBytes(st.ToCharArray( ));

sock.Send(b2,b2.Length,0);

filestream.Close( );

}

7 2 net ftp5
7.2 .NET中的FTP编程

7.2.2 服务器端开发

else if(richTextBox2.Lines[j-2].ToString( )=="@@@@@@")

{

control=true;

}

}

}

}

}

7.“关闭服务”按钮的Click事件代码

private void button2_Click(object sender, System.EventArgs e)

{

try

{

control=true;

listener.Stop( );

statusBarPanel1.Text="停止监听";

}

catch{MessageBox.Show("监听还未开始,关闭无效。");}

}

8.“退出服务”按钮的Click事件代码

private void button3_Click(object sender, System.EventArgs e)

{

Application.Exit( );

}

7 2 net ftp6
7.2 .NET中的FTP编程

7.2.3 客户端开发

1.界面设计

如图7.6所示,在窗体上拖放5个Label控件、3个TextBox控件、3个Button控件、1个GroupBox控件、1个RichTextBox控件、1个StatusBar控件、1个ComboBox控件、1个saveFileDialog控件。设置各个控件的属性如表7.11所示。

7 2 net ftp7
7.2 .NET中的FTP编程

7.2.3 客户端开发

2.在代码窗口中添加引用

图7.6 客户端窗口

using System.Net;

using System.Net.Sockets;

using System.IO;

using System.Threadingt;

3.在代码窗口中添加私有成员

private bool control=false;

private TcpClient client;

private int i;

private NetworkStream netStream;

private FileStream fileStream=null;

private Stream stream=null;

图7.6客户端窗口

7 2 net ftp8
7.2 .NET中的FTP编程

7.2.3 客户端开发

4.“连接”按钮的Click事件代码

private void button1_Click(object sender, System.EventArgs e)

{

int port=0;

IPAddress myIP=IPAddress.Parse("127.0.0.1");

try

{

myIP=IPAddress.Parse(textBox3.Text);

}

catch{MessageBox.Show("您输入的IP地址格式错误!");}

client=new TcpClient( );

try

{

port=Int32.Parse(textBox2.Text);

}

catch{MessageBox.Show("请输入整数。");}

try

{

if(textBox1.Text!=" "&&textBox3.Text==" ")

{

client.Connect(textBox1.Text,port);

statusBarPanel1.Text="与服务器建立连接";

//获取网络流

netStream=client.GetStream( );

//读数据

byte[] b=new byte[6400];

i=netStream.Read(b,0,6400);

string str=System.Text.Encoding.BigEndianUnicode.GetString(b);

7 2 net ftp9
7.2 .NET中的FTP编程

7.2.3 客户端开发

richTextBox1.AppendText(str);

int j=richTextBox1.Lines.Length;

for(int k=0;k<j-1;k++)

{

comboBox1.Items.Add(richTextBox1.Lines[k]);

}

comboBox1.Text=comboBox1.Items[0].ToString( );

}

if(textBox3.Text!=""&&textBox1.Text=="")

{

client.Connect(myIP,port);

statusBarPanel1.Text="与服务器建立连接";

netStream=client.GetStream( );

byte[] b=new byte[6400];

int i=netStream.Read(b,0,6400);

string str=System.Text.Encoding.BigEndianUnicode.GetString(b);

richTextBox1.AppendText(str);

int j=richTextBox1.Lines.Length;

for(int k=0;k<j-1;k++)

{

comboBox1.Items.Add(richTextBox1.Lines[k]);

}

comboBox1.Text=comboBox1.Items[0].ToString( );

}

7 2 net ftp10
7.2 .NET中的FTP编程

7.2.3 客户端开发

if(textBox3.Text!=""&&textBox1.Text!="")

{

client.Connect(myIP,port);

statusBarPanel1.Text="与服务器建立连接";

netStream=client.GetStream( );

byte[] b=new byte[6400];

int i=netStream.Read(b,0,6400);

string str=System.Text.Encoding.BigEndianUnicode.GetString(b);

richTextBox1.AppendText(str);

int j=richTextBox1.Lines.Length;

for(int k=0;k<j-1;k++)

{

comboBox1.Items.Add(richTextBox1.Lines[k]);

}

comboBox1.Text=comboBox1.Items[0].ToString( );

}

}

catch(Exception ex){MessageBox.Show(ex.Message);}

}

5.“下载”按钮的Click事件代码

private void button2_Click(object sender, System.EventArgs e)

{

control=false;

if(saveFileDialog1.ShowDialog( )==DialogResult.OK)

{

//创建新的文件流

filestream=new FileStream(saveFileDialog1.FileName,FileMode.OpenOrCreate,FileAccess.Write);

//获取服务器网络流

netStream=client.GetStream( );

string down=comboBox1.Text+"\r\n";

byte[] b=System.Text.Encoding.BigEndianUnicode.GetBytes(down.ToCharArray( ));

7 2 net ftp11
7.2 .NET中的FTP编程

7.2.3 客户端开发

//发送要下载的文件名给服务器

netStream.Write(b,0,b.Length);

//流刷新

netStream.Flush( );

//启动接收文件的线程

Thread thread=new Thread(new ThreadStart(download));

thread.Start( );

}

}

6.Download( )方法的定义

//此方法用于接收服务器传来的流(要下载的文件)

private void download( )

{

Stream stream=null;

//获取网络流

stream=client.GetStream( );

int length=1024;

byte[] b=new byte[1024];

int num=stream.Read(b,0,length);

//读取网络流并写入文件

while(num>0)

{

//读取服务器流

string str=System.Text.Encoding.ASCII.GetString(b);

int m=str.IndexOf("<EOF>");

if(m==-1)

{

filestream.Write(b,0,num);

filestream.Flush( );

statusBarPanel1.Text="正在下载文件";

}

7 2 net ftp12
7.2 .NET中的FTP编程

7.2.3 客户端开发

else

{

filestream.Write(b,0,m);

filestream.Flush( );

break;

}

}

filestream.Close( );

MessageBox.Show("下载完毕!");

statusBarPanel1.Text="文件下载完毕";

}

7.“关闭”按钮的Click事件代码

private void button3_Click(object sender, System.EventArgs e)

{

try

{

netStream=client.GetStream( );

string end="@@@@@@"+"\r\n";

byte[] byt=System.Text.Encoding.BigEndianUnicode.GetBytes(end.ToCharArray( ));

netStream.Write(byt,0,byt.Length);

netStream.Flush( );

client.Close( );

statusBarPanel1.Text="与服务器断开连接";

}

catch{}

}