C# 网络编程技术教程

29
1 C# 网网网网网网网网 第第第 FTP 第第

description

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

Transcript of C# 网络编程技术教程

Page 1: C# 网络编程技术教程

1C# 网络编程技术教程

第七章 FTP 编程

Page 2: C# 网络编程技术教程

第7

章 FTP

程 2学习目标

•了解 FTP 的相关基础知识。•掌握 .NET 中 FTP 的服务器端编程方法。•掌握 .NET 中 FTP 的客户端编程方法。

Page 3: C# 网络编程技术教程

第7

章 FTP

程 3本章内容

7.1 FTP 概述

7.2 .NET 中的 FTP 编程

Page 4: C# 网络编程技术教程

第7

章 FTP

程 47.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 的目的为: 文件共享。 通过应用程序直接或间接使用远程主机。 提供一致性的协议,避免用户在不同主机上产生不同的操作方式。 提供可靠及有效率的数据传输。

Page 5: C# 网络编程技术教程

第7

章 FTP

程 57.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 间的交互界面。

Page 6: C# 网络编程技术教程

第7

章 FTP

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

命 令 格 式 描 述

用户名( USER ) USER ××××××

参数是标记用户的 Telnet 串。 Telnet 是一种 Internet 远程终端访问标准,它真实地模仿远程终端但不具有图形功能,只提供基于字符界面的访问。 Telnet 允许任何合法用户提供远程访问权,且不需特殊约定

口令( PASS ) PASS ××××××

参数是标记用户口令的 Telnet 串。在访问非匿名 FTP 服务器时,该命令是必需的

账号( ACCT ) ACCT ×××××× 参数是标记用户账户的 Telnet 串

重新初始化( REIN ) REIN

该命令终止 USER ,将所有 I/O 和账户信息写入,但不许进行中的数据传输完成。重置所有参数,控制连接打开,可以再次开始 USER 命令

退出登录( QUIT ) OUIT

该命令终止 USER ,如果没有数据传输,服务器关闭控制连接;如果有数据传输,在得到传输响应后服务器关闭控制连接

放弃( ABOR ) ABOR 该命令用于通知服务中止以前的 FTP 命令和与之相关的数据传送

Page 7: C# 网络编程技术教程

第7

章 FTP

程 77.1 FTP 概述 7.1.2 FTP 命令

命 令 格 式 描 述

改变工作目录( CWD ) CWD 目录名 该命令使用户可以在不同的目录或数据集下工作而不用改变它的登录或账户信息

回到上一层目录( CDUP ) CDUP 该命令要求系统回到上一级目录

删除( DELE ) DELE 文件名 该命令删除指定路径下的文件

列举子目录或文件( LIST ) LIST 目录名 该命令列举指定目录下的子目录或文件

列举子目录或文件( NLST ) NLST 目录名 该命令列举指定目录下的子目录或文件

创建目录 (MKD) MKD 目录名 该命令在指定路径下创建目录

显示当前路径( PWD ) PWD 该命令显示当前路径

删除目录( RMD ) RMD 目录名 该命令删除指定目录

重命名( RNFR ) RNFR 文件名 (旧的 ) 该命令注明将被改变的文件名

重命名为( RNTO ) RNTO 文件名 ( 新的 )该命令注明新的文件名(与 RNFR 共同完成文件的重命名)

结构加载 (SMNT) SMNT 文件目录名 该命令使用户在不改变登录或账户信息的情况下加载另一个文件系统数据结构

Page 8: C# 网络编程技术教程

第7

章 FTP

程 87.1 FTP 概述

命 令 格 式 描 述

TYPETYPE A(ASCII) or E(EBCDIC) or I(Image) or N(Nonprint)

or T(TELNET)该命令定义文件类型以及打印格式

STRU STRU F(File) or R(Record),P(Page) 该命令定义数据的组织形式

MODE MODE S (Stream) or B (Block) or C (Compressed) 该命令定义传输模式

7.1.2 FTP 命令

命 令 参 数 描 述

数据端口( PORT ) PRT 6-Digit identifier

客户端选择端口,格式为 a,b,c,d,e,f ,其中前 4位为 IP 地址,后两位为端口,计算公式:端口 = e256+f

被动( PASV ) PASV 主机和端口地址

该命令要求服务器 DTP 在指定的数据端口侦听,进入被动接收请求的状态

Page 9: C# 网络编程技术教程

第7

章 FTP

程 97.1 FTP 概述 7.1.2 FTP 命令

命 令 格 式 描 述

获得文件 (RETR)

RETR 文件名 该命令使服务器 DTP 传送指定路径内的文件复本到服务器或用户 DTP

保存 (STOR) STOR 文件名 该命令使服务器 DTP 接收数据连接上传送过来的数据,并将数据保存在服务器的文件中。如果文件已存在,则覆盖它

附加 (APPE) APPE 文件名 与 STOR 类似,如果文件存在,数据附加在文件之后

分配空间 (ALLO) ALLO 文件名 该命令在服务器上分配文件的空间

重新开始 (REST) REST 文件名 重新开始传输文件,该命令后应该跟其他文件传输的 FTP 命令

状态 (STAT)

STAR 文件名 该命令返回控制连接状态

命 令 格 式 描 述

帮助 (HELP) HELP 该命令表示获取帮助

等待 (NOOP) NOOP 该命令仅使服务器返回 OK

站点参数( SITE ) SITE 该命令提供服务器系统信息,信息因系统不同而不同

系统 (SYST) SYST 该命令用于确定服务器上运行的操作系统

Page 10: C# 网络编程技术教程

第7

章 FTP

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

响 应 码 含 义 响 应 码 含 义

110 重新启动标记应答 332 登录时需要账户信息

120 服务器准备就绪的时间(分钟数) 350 请求的文件操作需要进一步命令

125 打开数据连接,开始传输 421 不能提供服务,关闭控制连接

150 文件状态良好,打开数据连接 425 无法打开数据连接

200 命令成功 426 关闭连接,中止传输

202 命令未执行 450 请求的文件操作未执行

211 系统状态 451 遇到本地错误

212 目录状态 452 磁盘空间不足

213 文件状态 500 格式错误,无效命令

Page 11: C# 网络编程技术教程

第7

章 FTP

程 117.1 FTP 概述 7.1.3 FTP 服务器响应码

214 帮助信息 501 参数语法错误

215 系统类型 502 命令未执行

220 服务就绪 503 命令顺序错误

221 服务关闭控制连接,可以退出登录 504 此参数下的命令功能未执行

225 打开数据连接 530 未登录网络

226 关闭数据连接,请求的文件操作成功 532 存储文件需要账户信息

227 进入被动模式( IP 地址、 ID 端口) 550 未执行请求的操作

230 登录因特网 551 不知道的页类型

250 请求的文件操作完成 552 超过存储分配

257 路径名建立 553 文件名不合法

331 用户名正确,需要密码

Page 12: C# 网络编程技术教程

第7

章 FTP

程 127.1 FTP 概述 7.1.3 FTP 服务器响应码

编 号 描 述

1 信息已被服务器正确接受,但被处理

2 信息已被服务器正确处理完毕

3 信息已被服务器正确接受,并正在处理中

4 信息处理错误(暂时)

5 信息处理错误(永久)

编 号 描 述

0 语法

1 系统状态与信息

2 与 FTP 服务器系统连接状态

3 与用户认证有关的信息

4 未定义

5 与文件系统有关的信息

Page 13: C# 网络编程技术教程

第7

章 FTP

程 137.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:

Page 14: C# 网络编程技术教程

第7

章 FTP

程 147.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>至此,完成用户确认的流程。

Page 15: C# 网络编程技术教程

第7

章 FTP

程 157.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,69200 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.

至此,数据传输结束。

Page 16: C# 网络编程技术教程

第7

章 FTP

程 167.1 FTP 概述 7.1.4 FTP流程 3.结束 FTP 流程如图 7.4 所示。当数据传输结束后,如不需要再进行其他文件传输,则 FTP 客户端发送 QUIT 命令,要求结束 FTP 连接。 FTP 服务器端则发回响应信息,表示结束连接。示例如下: ftp> quit221 Server closing control connection. Goodbye.

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

Page 17: C# 网络编程技术教程

第7

章 FTP

程 177.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 是要写入的数据。代码首先检查文件是否存在,如果不存在就创建一个新文件。

Page 18: C# 网络编程技术教程

第7

章 FTP

程 187.2 .NET 中的 FTP 编程 7.2.2 服务器端开发 1.界面设计 如图 7.5 所示,在窗体上拖放 3 个 Label 控件、 1 个 TextBox 控件、 3 个Button 控件、 2 个 RichTextBox 控件、 1 个 StatusBar 控件。设置各个控件的属性如表 7.10 所示。

控 件 属 性 值

label1 Text 监听端口:

label2 Text 文件列表:

label3 Text 客户信息:

button1 Text 开始服务

button2 Text 关闭服务

button3 Text 退出服务

richTextBox1 Text 清空

richTextBox1 Text 清空

textBox1 Text 清空

statusBar1

Text 清空

Panels statusBarPanel1

ShowPanels True

Page 19: C# 网络编程技术教程

第7

章 FTP

程 197.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 服务器端窗口

Page 20: C# 网络编程技术教程

第7

章 FTP

程 207.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);

Page 21: C# 网络编程技术教程

第7

章 FTP

程 217.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( ); }

Page 22: C# 网络编程技术教程

第7

章 FTP

程 227.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( );}

Page 23: C# 网络编程技术教程

第7

章 FTP

程 237.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 所示。

控 件 属 性 值

groupBox1 Text 服务器(名称或 IP 地址)

label1 Text 服务器名称:

label2 Text 服务器 IP 地址:

label3 Text 端口:

label4 Text 服务器文件列表:

label5 Text 选择下载文件:

button1 Text 连接

button2 Text 下载

button3 Text 关闭

richTextBox1 Text 清空

comboBox Text 清空

textBox1 Text 清空

textBox2 Text 清空

textBox3 Text 清空

saveFileDialog1 Text 清空

statusBar1

Text 清空

Panels statusBarPanel1

ShowPanels True

Page 24: C# 网络编程技术教程

第7

章 FTP

程 247.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 客户端窗口

Page 25: C# 网络编程技术教程

第7

章 FTP

程 257.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);

Page 26: C# 网络编程技术教程

第7

章 FTP

程 267.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( ); }

Page 27: C# 网络编程技术教程

第7

章 FTP

程 277.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( ));

Page 28: C# 网络编程技术教程

第7

章 FTP

程 287.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="正在下载文件 "; }

Page 29: C# 网络编程技术教程

第7

章 FTP

程 297.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{} }