当前位置:首页 » 文件传输 » ftp文件单线程下载计算公式
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

ftp文件单线程下载计算公式

发布时间: 2022-12-11 18:22:46

① 关于FTP资源的问题

很多朋友喜欢上网下载软件、电影、音乐等。但有时他们会遇到这样的问题,费很大劲就是找不到自己需要的东西。是网上真的没有吗?网络经过这几年快速发展,这种可能性多数时候并不大。更大的可能性是,他们忽略了大量的隐性FTP资源!要知道,某些搜索引擎找不到的文件,常常可以在这里找到!这里,我们大体分两种方式,一种是用软件搜索,另一种是通过FTP搜索引擎。下面分别予以介绍。

软件搜索:下面两款免费软件,分别以不同方式搜索网上FTP资源,可以满足网友的不同需求。

1.AnonymousFTPSearch 软件版本:1.2,软件大小为129kb,为免费软件。
软件特点:这是个英文软件,可以找出包含指定关键字的匿名FTP站点,可以浏览站点目录结构,可以同时下载多个文件。

使用方法:这个软件无需设置,一般情况下,用户只要在Word下输入关键字,然后按下“Search”按钮即可搜索。关键字常用“anonymousftp”或者“anonymousftpxxx”格式,比如“anonymousftpmp3”。这个软件借助了搜索引擎的威力,默认采用最强的Google。当然,你也可以改成其它的,但要注意,目前只支持常见搜索引擎,而且只支持GET方式。窗口上的“MaxPages”,是指定利用搜索结果的前面多少页,默认是33页,一般不必改动。搜索期间,可以随时按“Stop”按钮或者ESC键停止搜索。

搜索到的匿名FTP站点出现在下面的结果窗口中,每个站点后面有Access栏,表明站点文件的读写权限。Time栏显示用户与站点的连接时间(秒),据此可以初步判断下载速度的快慢。点击“Copyresults”按钮,可以复制搜索结果。按“Exporttofile”按钮,可以将结果保存为一个TXT文本文件,以备其它FTP工具使用。我们也可以直接双击结果窗口中的FTP站点,查看站点的目录和文件结构,双击文件名,就可以下载它。这个软件允许同时下载多个文件。

2.SFtp;软件版本为10.0,软件大小为472kb,为免费软件。
这是由国人开发的中文软件,可以找出指定网段内的所有FTP站点,包括匿名的和非匿名的,进而利用它的查找功能,找出那些站点、目录下有我们需要的文件。比起AnonymousFTPSearch来,它有一个明显的好处,就是我们可以就近搜索哪些FTP主机上有自己需要的文件,这样可以加快下载速度,对普通拨号上网用户意义重大。同样,SFtp也可以直观浏览匿名FTP站点目录和文件结构,可以直接同时下载多个文件。

这是个绿色软件,无需安装,双击文件即可启动。在“开始IP”输入网段的起始IP地址,如“216.120.0.0”,在“结束IP”输入结束IP地址,如“216.120.255.255”,按下“开始搜索”按钮即可。搜索到的FTP站点会出现在中间窗格。地址前面有钥匙标志的,表明是非匿名站点,必须凭用户名和密码才能访问;有人像标志的,表明目前登录人数太多,已无法再进去了;只有一个显示器标志的,表明是匿名站点,可以随意访问。双击匿名站点,可以用指定Ftp软件打开站点,初始状态下是用默认浏览器,在SFtp窗口上点击菜单“操作/设置/其它”,可以设定你所用的Ftp软件。单击匿名站点前面的加号,可以浏览目录、文件结构,在文件或者目录上右击鼠标,选择“目标另存为”,可以下载所选文件或者目录。如果通过浏览方式没发现你想要的文件,可以点击窗口左边的“查找”按钮搜索。

本软件每搜索500个IP地址,便自动保存一次结果,搜索结束时也会自动保存,文件名为“起始IP-结束IP.txt”,保存位置在SFtp所在目录。另外,SFtp是多线程搜索软件,Windows95/98/ME下的默认线程为80个,在WindowsNT/2000/XP下为500个,可以调整,但Windwos95/98/ME下不超过120为宜。强烈推荐在Windows2000下运行本软件,这样,速度要比在Windows98下快数倍以上。

FTP搜索引擎
这里推荐北京大学的“天网FTP”搜索引擎,网址http://bingle.pku.e.cn/。它速度快、容量大、功能强。它的用法跟一般搜索引擎差不多,在搜索框输入要找的文件名,可以包含“�”号(代表多个字符)、“?”号(代表单个字符)、空格(表示几个关键字是并的关系),点击“搜索FTP文件”,瞬间即可得到查询结果。我们知道,有的FTP站点并不是一直有效的,而这个搜索引擎可以检测出站点目前是否可以连接,避免了我们作无谓的尝试。为了缩小搜索范围,搜索之前可以在搜索框右侧选定文件类别,分为“图像”、“声音”、“视频”、“压缩”、“文档”、“程序”、“目录”、“源代码”等。如果采用复杂搜索,还可以限定文件大小、日期等。要想获得更多技巧,可以看看它的页面帮助。关于搜索结果的排列,这个搜索引擎也作了周密考虑。首先,通过每个结果前面直观的图标,我们可以立即辨认出哪个是目录、哪个是ZIP压缩包、哪个是文本文件、哪个是视频文件、哪个是音乐文件等等。其次,可以按文件日期、大小、相关度等,对搜索结果进行重新排序。另外,还可以使用它的“在结果中查找”功能,在搜索结果中找出所需文件。这些都方便了用户以最快速度找到自己真正需要的东西

在搜索过程中,往往会有意外发现,让人兴奋不已。你不想试试吗?

如今的个人主页几乎一下子全变成论坛形式了,而许多好东东再也无法像过去那样直接从网页上以HTTP方式下载了!要登陆各个论坛去找,页且绝大部分论坛提供的资源大都是FTP下载,一下子FTP成为最流行的资源共享方式了.那么,如何才能最大限度地利用好FTP资源呢?
一,注意FTP着站点的下载限制

现在许多FTP站点出于自身安全考虑都限制了用户登录数量,如果在你的连接过程中FTP工具显示"421 too manyusen"信息,说明该站已人满为患了,只能稍后再.而越来越多的FTP站点现在都限制为单线下载,那些习惯于使用网络蚂蚁式FlasGel用多线程下载的朋友只能接受残酷现实,必须按该FTP站点的要求设为单线下载,由于有些站点对于同一IP多线程下载进行封杀,所以需按要求办事.

二,善于收集FTP的站点的账号和密码
最直接的方法就是到各个论坛的公告区去查看密码。由于现在盗链现象比较严重,大部分站点都不定期更必自己的FTP下载密码。如果你用FTP工具连不上了,可能是密码已经换了。在论坛的讨论区经常能看到会员之间相互交流资源的链接,如果发现一个像ftp//usemame:[email protected]/md/ftp.zip:21这样的链接,它可不仅能下载到某个软件,它还能告诉你一个FTP站点的完整信息:站点地址:200.100.001.002用户名:usemame,密码:password,端口:21.用你的FTP工具连上去看看还有什么其他好东东!

三,多快好省下载FTP资源
虽然各种FTP工具如GUTEFTP、FLASHFXP等都能直接下载这类资源,但这里还是推荐使用专用下载工具,专用的下载工具不但可以同时下载不同的链接,而且断点续传的能力很强,把它设成总是重试就不用我们操心了,只等收获吧!网际快车是综合起来最适合普通用户了!

1、下载FTP站点的资源
现在就以FlashFXP及网际快车为例进行介绍:用FlashFXP连到某一站点,在FTP站点中找到自己想要下载的文件,然后右键点击它,在快捷菜单中选“复制URL”,如果头一次对该站点进行URL复制,需要在弹出的密码框中输入当前账号的密码。这时链接已经复制完成可以直接下载,也可以把地址转到其它专业下载工具中使用。再打开网际快车,添加一新任务,在URL文本框中粘贴刚才复制的链接,将线程数目设为1个(绝大多数FTP站点只提供一个线程),点击确定开始下载。对于LIST账号的还要用户名和密码。

2、下载FTP链接
对于网页上没提供账号和密码的链接,需手工加入账号和密码。在网际快车的添加任务窗口选中"认证“复选框,在用户和口令栏中输入账号和密码就可以了(当然支持匿名下载的链接就不需要设置了)。

3、巧用代理实现”多线程“下载现在绝大多楼FTP站点只提供单线程下载,当你需要下载同一站点上的数个文件时,只能一个接一个慢慢地下载。但如果手头有可用的代理服务器的话,就能突破此限制,同时下载多个文件(这里说的多线程不是传统意义上的多线程下载单文件,而是无队列等待同时下载多个文件)。用代理服务器下载是通过代理服务器的IP地址来登录FTP站点,所以不会和自己的真实Ip地址发生冲突。假如你使用1个代理服务器,就可以让一个文件直接下载,一个文件通过代理下载,这样就可以不排队面同时下载两个文件了!

首先把最常见的三个代码列出来:
421 这表示该帐号目前允许登入人数已满,请稍后再试
530 这表示所输入的密码错误,请再确定所输入的密码是否正确
550这表示该文件已不存在,通常的情形应该是该文件已经被删除,无法下载;但有时候也会因为文件名错误而无法下载,请再次检查所输入的文件名是否正确。

这种错误跟http协议类似,大致是:
2开头--成功
3开头--权限问题
4开头--文件问题
5开头--服务器问题

② 关于FTP的带宽

网络带宽可分为上行速率(上传的带宽)和上行速率(下载的带宽)。上行速率是指用户电脑向网络发送信息时的数据传输速率,比如用FTP上传文件到网上去,影响上传速度的就是“上行速率”;下行速率是指网络向用户电脑发送信息时的传输速率,从网上下载文件,影响下载速度的就是“下行速率”。当然,在实际上传下载过程中,线路、设备(含计算机及其他设备)等的质量也会对速度造成或多或少的影响。使用的ADSL是非对称的传输方式,即上行速率不等于下行速率;ADSL上行速率640Kbps到1Mbps,下行速率10Mbps到100Mbps。普遍的是20Mbps,注意下行速率不等于下载速率,平时我们下载软件或者电影的时候经常只能达到1Mbps,而不是20Mbps,其实20M的宽带是20M位(bit)的而不是20M字节(Byte)的。根据8位(Bit)=1字节(Byte)的公式我们来算一下:20Mbit=20480Kbit=2560KByte,所以理论上20M的宽带下载最大速度应该是2M,再因为一些其他的因素,实际的下载速度在2M左右是正常的。

③ 怎么从FTP上下载东西

先假设有一FTP服务器,FTP服务器:qint.ithot.net,用户名:username 密码:user1234。在本地电脑D:盘创建一个文件夹"qint"。将要上传的文件复制到d:\qint里。通过FTP命令将文件从本地上传,从服务器下载的步骤如下:

1.“开始”-“运行”-输入“FTP”

2.open qint.ithot.net
/*这一步可以与第一步合并,在“运行”里直接输入"ftp qint.ithot.net"。如果你的FTP服务器不是用的21默认端口,假如端口是2121,那么此步的命令应在后面空格加2121,即“open qint.ithot.net 2121”*/

3.username
/*提示你输入用户名*/

4.user1234
/*提示你输入密码,密码不回显,打完密码后回车即可。如果你的密码输入错误,将不会提示你重新输入,这时你要键入“user”命令,将会出现第三步,你可以重新输入用户名和密码。*/

5.dir
/*你成功登陆后就可以用dir查看命令查看FTP服务器中的文件及目录,用ls命令只可以查看文件。*/

6.mkdir qint
/*在FTP服务器上根目录下建立qint目录。*/

7.cd qint
/*进入目录qint,用“cd 你的目录名”可以进入当前目录的下一级目录,这跟DOS一样。*/

8.bin
/*采用二进制传输。如果你要上传下载,这一步很重要,不先执行这个命令,上传下载会很慢。*/

9.lcd d:\qint
/*定位本地默认文件夹,在前面我事先在D:盘创建的。*/

10.!dir
/*查看本地文件夹中的文件及目录*/

11.put i001.jpg
/*将当前目录(d:\qint)中的文件i001.jpg上传到FTP服务器默认目录。可以用"mput *.*"将所有文件上传到FTP服务器上。*/

12.get d123.jpg
/*将FTP服务器默认目录中的文件d123.jpg下载到当前目录下(d:\qint)。可以用"mget *.*"将所有文件下载到d:\qint*/

13.delete *.*
/*删除目录qint中的所有文件。*/

14.cd ..
/*返回至上一级目录,即根目录。返回上一级目录用“cd ..”要注意,中间有空格。返回根目录用“cd \”。*/

15.mrdir qint
/*删除目录qint。删除目录,在此目录下不能有文件及目录,不然将无法删除。*/

16.bye
/*退出FTP服务器*/

上传下载时特别要注意服务器及本地电脑的当前目录,文件是从哪里到哪里的问题。查看FTP服务器的当前目录命令为pwd,可以用cd命令定位服务器的目录。可以用lcd命令定位本地电脑的目录。以上实例应用到了采用FTP命令行方式上传下载的最常用命令,你还可以用命令“?”查看更多的命令。

FTP命令详解
FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用FTP,都会遇到大量的FTP内部命令。熟悉并灵活应用FTP的内部命令,可以大大方便使用者,并收到事半功倍之效。

FTP的命令行格式为:ftp -v -d -i -n -g [主机名],其中

-v显示远程服务器的所有响应信息;

-n限制ftp的自动登录,即不使用;

.n etrc文件;

-d使用调试方式;

-g取消全局文件名。

ftp使用的内部命令如下(中括号表示可选项):

1.![cmd[args]]:在本地机中执行交互shell,exit回到ftp环境,如:!ls*.zip.

2.$ macro-ame[args]:执行宏定义macro-name.

3.account[password]:提供登录远程系统成功后访问系统资源所需的补充口令。

4.append local-file[remote-file]:将本地文件追加到远程系统主机,若未指定远程系统文件名,则使用本地文件名。

5.ascii:使用ascii类型传输方式。

6.bell:每个命令执行完毕后计算机响铃一次。

7.bin:使用二进制文件传输方式。

8.bye:退出ftp会话过程。

9.case:在使用mget时,将远程主机文件名中的大写转为小写字母。

10.cd remote-dir:进入远程主机目录。

11.cp:进入远程主机目录的父目录。

12.chmod mode file-name:将远程主机文件file-name的存取方式设置为mode,如:chmod 777 a.out。

13.close:中断与远程服务器的ftp会话(与open对应)。

14.cr:使用asscii方式传输文件时,将回车换行转换为回行。

15.delete remote-file:删除远程主机文件。

16.debug[debug-value]:设置调试方式,显示发送至远程主机的每条命令,如:deb up 3,若设为0,表示取消debug。

17.dir[remote-dir][local-file]:显示远程主机目录,并将结果存入本地文件local-file。

18.disconnection:同close。

19.form format:将文件传输方式设置为format,缺省为file方式。

20.get remote-file[local-file]:将远程主机的文件remote-file传至本地硬盘的local-file。

21.glob:设置mdelete,mget,mput的文件名扩展,缺省时不扩展文件名,同命令行的-g参数。

22.hash:每传输1024字节,显示一个hash符号(#)。

23.help[cmd]:显示ftp内部命令cmd的帮助信息,如:help get。

24.idle[seconds]:将远程服务器的休眠计时器设为[seconds]秒。

25.image:设置二进制传输方式(同binary)。

26.lcd[dir]:将本地工作目录切换至dir。

27.ls[remote-dir][local-file]:显示远程目录remote-dir,并存入本地文件local-file。

28.macdef macro-name:定义一个宏,遇到macdef下的空行时,宏定义结束。

29.mdelete[remote-file]:删除远程主机文件。

30.mdir remote-files local-file:与dir类似,但可指定多个远程文件,如:mdir *.o.*.zipoutfile

31.mget remote-files:传输多个远程文件。

32.mkdir dir-name:在远程主机中建一目录。

33.mls remote-file local-file:同nlist,但可指定多个文件名。

34.mode[modename]:将文件传输方式设置为modename,缺省为stream方式。

35.modtime file-name:显示远程主机文件的最后修改时间。

36.mput local-file:将多个文件传输至远程主机。

37.newer file-name:如果远程机中file-name的修改时间比本地硬盘同名文件的时间更近,则重传该文件。

38.nlist[remote-dir][local-file]:显示远程主机目录的文件清单,并存入本地硬盘的local-file。

39.nmap[inpattern outpattern]:设置文件名映射机制,使得文件传输时,文件中的某些字符相互转换,如:nmap $1.$2.$3[$1,$2].[$2,$3],则传输文件a1.a2.a3时,文件名变为a1,a2。该命令特别适用于远程主机为非UNIX机的情况。

40.ntrans[inchars[outchars]]:设置文件名字符的翻译机制,如ntrans 1R,则文件名LLL将变为RRR。

41.open host[port]:建立指定ftp服务器连接,可指定连接端口。

42.passive:进入被动传输方式。

43.prompt:设置多个文件传输时的交互提示。

44.proxy ftp-cmd:在次要控制连接中,执行一条ftp命令,该命令允许连接两个ftp服务器,以在两个服务器间传输文件。第一条ftp命令必须为open,以首先建立两个服务器间的连接。

45.put local-file[remote-file]:将本地文件local-file传送至远程主机。

46.pwd:显示远程主机的当前工作目录。

47.quit:同bye,退出ftp会话。

48.quote arg1,arg2...:将参数逐字发至远程ftp服务器,如:quote syst.

49.recv remote-file[local-file]:同get。

50.reget remote-file[local-file]:类似于get,但若local-file存在,则从上次传输中断处续传。

51.rhelp[cmd-name]:请求获得远程主机的帮助。

52.rstatus[file-name]:若未指定文件名,则显示远程主机的状态,否则显示文件状态。

53.rename[from][to]:更改远程主机文件名。

54.reset:清除回答队列。

55.restart marker:从指定的标志marker处,重新开始get或put,如:restart 130。

56.rmdir dir-name:删除远程主机目录。

57.runique:设置文件名唯一性存储,若文件存在,则在原文件后加后缀..1,.2等。

58.send local-file[remote-file]:同put。

59.sendport:设置PORT命令的使用。

60.site arg1,arg2...:将参数作为SITE命令逐字发送至远程ftp主机。

61.size file-name:显示远程主机文件大小,如:site idle 7200。

62.status:显示当前ftp状态。

63.struct[struct-name]:将文件传输结构设置为struct-name,缺省时使用stream结构。

64.sunique:将远程主机文件名存储设置为唯一(与runique对应)。

65.system:显示远程主机的操作系统类型。

66.tenex:将文件传输类型设置为TENEX机的所需的类型。

67.tick:设置传输时的字节计数器。

68.trace:设置包跟踪。

69.type[type-name]:设置文件传输类型为type-name,缺省为ascii,如:type binary,设置二进制传输方式。

70.umask[newmask]:将远程服务器的缺省umask设置为newmask,如:umask 3。

71.user user-name[password][account]:向远程主机表明自己的身份,需要口令时,必须输入口令,如:user anonymous my@email。

72.verbose:同命令行的-v参数,即设置详尽报告方式,ftp服务器的所有响应都将显示给用户,缺省为on.

73.?[cmd]:同help。

④ FileZilla上传下载时怎样设置成单线程的

设置步骤如下:

1、启动FileZilla,点击Edit菜单 ->Settings...命令;

2、打开对话框中,在如图红线处修改为1,点击确定即可。

⑤ 关于如何实现FTP上传或者下载带进度和速率的实现方法

在这里需要说明的是,该方式是通过其他代码进行改进的。 首先我们需要定义一个委托,用来实现传输过程中传递文件的总数,已完成的字节数和速度,方便客户端界面上调用。 public delegate void TransferProcess(long total,long finished,double speed); 调用代码就不举例了 接下来我们建立一个FTPClient类,该类基于socket和FTP协议实现了连接FTP服务,建立目录,上传文件,下载文件等主要方法。结构如下: 需要注意的是,我们需要定一个事件event TransferProcess OnTransferProcess;该事件在实例化FTPClient之后需要调用,这个事件对实现进度条和速率是非常重要的。为了实现速率我们还需要定义个公开的成员startTime(开始时间)。我们现在主要是看一下如何上传的。 /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { //连接服务器 if (!bConnected) { Connect(); } UpdateStatus = true; //建立socket连接 Socket socketData = CreateDataSocket(); //向FTP服务器发生存储命令 SendCommand("STOR " + Path.GetFileName(strFileName)); //如何服务器返回的信息不是我们所需要的,就抛出异常 if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4)); } //建立本地文件的数据流 FileStream input = new FileStream(strFileName, FileMode.Open); int iBytes = 0; long total = input.Length;//该成员主要记录文件的总字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 long finished = 0;//该成员主要记录已经传输完成的字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 double speed = 0;//记录传输的速率 while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0)//循环从本地数据流中读取数据到缓冲区 { //Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0);//将缓冲区的数据发送到FTP服务器 DateTime endTime = DateTime.Now;//每次发送数据的结束时间 TimeSpan ts = endTime - startTime;//计算每次发送数据的时间间隔 finished += iBytes;//计算完成的字节数. Console.WriteLine(ts.Milliseconds); //计算速率,注意finished是字节,所以需要换算冲K字节 if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } //这里是必不可少的,否则你无法实现进度条 //如果传输进度事件被实例化,而且从本地数据流中读取数据不是空的并完成的字节数也不为空的话,则实现委托. if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close();//当传输完成之后需要关闭数据流,以便下次访问. if (socketData.Connected) { socketData.Close();//关闭当前的socket } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } 上面代码中注释写得比较详细,这里就不再一一讲解了,关于下载中实现进度条和速率的问题可以参考以上代码进行修改. 完整的代码如下: using System; using System.net; using System.IO; using System.Text; using System.net.Sockets; namespace MMSEncoder { public delegate void TransferProcess(long total,long finished,double speed); /// /// FTP Client /// public class FTPClient { public event TransferProcess OnTransferProcess; public bool UpdateStatus = true; public DateTime startTime; private bool IsAbortConnect = false; #region 构造函数 /// /// 缺省构造函数 /// public FTPClient() { strRemoteHost = ""; strRemotePath = ""; strRemoteUser = ""; strRemotePass = ""; strRemotePort = 21; bConnected = false; } /// /// 构造函数 /// /// FTP服务器IP地址 /// 当前服务器目录 /// 登录用户账号 /// 登录用户密码 /// FTP服务器端口 public FTPClient(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort) { strRemoteHost = remoteHost; strRemotePath = remotePath; strRemoteUser = remoteUser; strRemotePass = remotePass; strRemotePort = remotePort; Connect(); } #endregion #region 登陆字段、属性 /// /// FTP服务器IP地址 /// private string strRemoteHost; public string RemoteHost { get { return strRemoteHost; } set { strRemoteHost = value; } } /// /// FTP服务器端口 /// private int strRemotePort; public int RemotePort { get { return strRemotePort; } set { strRemotePort = value; } } /// /// 当前服务器目录 /// private string strRemotePath; public string RemotePath { get { return strRemotePath; } set { strRemotePath = value; } } /// /// 登录用户账号 /// private string strRemoteUser; public string RemoteUser { set { strRemoteUser = value; } } /// /// 用户登录密码 /// private string strRemotePass; public string RemotePass { set { strRemotePass = value; } } /// /// 是否登录 /// private Boolean bConnected; public bool Connected { get { return bConnected; } } #endregion #region 链接 /// /// 建立连接 /// public void Connect() { //if (IsAbortConnect) throw new IOException("用户强制终止了FTP"); socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort); // 链接 try { socketControl.Connect(ep); } catch (Exception) { throw new IOException("无法连接到远程服务器!"); } // 获取应答码 ReadReply(); if (iReplyCode != 220) { DisConnect(); throw new IOException(strReply.Substring(4)); } // 登陆 SendCommand("USER " + strRemoteUser); if (!(iReplyCode == 331 || iReplyCode == 230)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } if (iReplyCode != 230) { SendCommand("PASS " + strRemotePass); if (!(iReplyCode == 230 || iReplyCode == 202)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } } bConnected = true; // 切换到初始目录 if (!string.IsNullOrEmpty(strRemotePath)) { ChDir(strRemotePath); } } /// /// 关闭连接 /// public void DisConnect() { if (socketControl != null) { SendCommand("QUIT"); } CloseSocketConnect(); } public void AbortConnect() { if (socketControl != null) { SendCommand("ABOR"); } IsAbortConnect = true; //CloseSocketConnect(); } #endregion #region 传输模式 /// /// 传输模式:二进制类型、ASCII类型 /// public enum TransferType { Binary, ASCII }; /// /// 设置传输模式 /// /// 传输模式 public void SetTransferType(TransferType ttType) { if (ttType == TransferType.Binary) { SendCommand("TYPE I");//binary类型传输 } else { SendCommand("TYPE A");//ASCII类型传输 } if (iReplyCode != 200) { throw new IOException(strReply.Substring(4)); } else { trType = ttType; } } /// /// 获得传输模式 /// /// 传输模式 public TransferType GetTransferType() { return trType; } #endregion #region 文件操作 /// /// 获得文件列表 /// /// 文件名的匹配字符串 /// public string[] Dir(string strMask) { // 建立链接 if (!bConnected) { Connect(); } //建立进行数据连接的socket Socket socketData = CreateDataSocket(); //传送命令 SendCommand("NLST " + strMask); //分析应答代码 if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226)) { throw new IOException(strReply.Substring(4)); } //获得结果 strMsg = ""; while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); strMsg += GB2312.GetString(buffer, 0, iBytes); if (iBytes < buffer.Length) { break; } } char[] seperator = { '
' }; string[] strsFileList = strMsg.Split(seperator); socketData.Close();//数据socket关闭时也会有返回码 if (iReplyCode != 226) { ReadReply(); if (iReplyCode != 226) { throw new IOException(strReply.Substring(4)); } } return strsFileList; } /// /// 获取文件大小 /// /// 文件名 /// 文件大小 public long GetFileSize(string strFileName) { if (!bConnected) { Connect(); } SendCommand("SIZE " + Path.GetFileName(strFileName)); long lSize = 0; if (iReplyCode == 213) { lSize = Int64.Parse(strReply.Substring(4)); } else { throw new IOException(strReply.Substring(4)); } return lSize; } /// /// 删除 /// /// 待删除文件名 public void Delete(string strFileName) { if (!bConnected) { Connect(); } SendCommand("DELE " + strFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件) /// /// 旧文件名 /// 新文件名 public void Rename(string strOldFileName, string strNewFileName) { if (!bConnected) { Connect(); } SendCommand("RNFR " + strOldFileName); if (iReplyCode != 350) { throw new IOException(strReply.Substring(4)); } // 如果新文件名与原有文件重名,将覆盖原有文件 SendCommand("RNTO " + strNewFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } #endregion #region 上传和下载 /// /// 下载一批文件 /// /// 文件名的匹配字符串 /// 本地目录(不得以\结束) public void Get(string strFileNameMask, string strFolder) { if (!bConnected) { Connect(); } string[] strFiles = Dir(strFileNameMask); foreach (string strFile in strFiles) { if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串 { if (strFile.LastIndexOf(".") > -1) { Get(strFile.Replace("\r", ""), strFolder, strFile.Replace("\r", "")); } } } } /// /// 下载一个文件 /// /// 要下载的文件名 /// 本地目录(不得以\结束) /// 保存在本地时的文件名 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName) { if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName; } if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName); st.Close(); } FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create); Socket socketData = CreateDataSocket(); SendCommand("RETR " + strRemoteFileName); if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); output.Write(buffer, 0, iBytes); if (iBytes <= 0) { break; } } output.Close(); if (socketData.Connected) { socketData.Close(); } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } } } /// /// 上传一批文件 /// /// 本地目录(不得以\结束) /// 文件名匹配字符(可以包含*和?) public void Put(string strFolder, string strFileNameMask) { string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask); foreach (string strFile in strFiles) { //strFile是完整的文件名(包含路径) Put(strFile); } } /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { if (!bConnected) { Connect(); } UpdateStatus = true; Socket socketData = CreateDataSocket(); SendCommand("STOR " + Path.GetFileName(strFileName)); if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4)); } FileStream input = new FileStream(strFileName, FileMode.Open); int iBytes = 0; long total = input.Length; long finished = 0; //DateTime startTime = DateTime.Now; double speed = 0; while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0) { Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0); DateTime endTime = DateTime.Now; TimeSpan ts = endTime - startTime; finished += iBytes; Console.WriteLine(ts.Milliseconds); if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close(); if (socketData.Connected) { socketData.Close(); } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } #endregion #region 目录操作 /// /// 创建目录 /// /// 目录名 public void MkDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("MKD " + strDirName); if (iReplyCode != 257) { throw new IOException(strReply.Substring(4)); } } /// /// 删除目录 /// /// 目录名 public void RmDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("RMD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 改变目录 /// /// 新的工作目录名 public void ChDir(string strDirName) { if (strDirName.Equals(".") || strDirName.Equals("")) { return; } if (!bConnected) { Connect(); } SendCommand("CWD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } this.strRemotePath = strDirName; } #endregion #region 内部变量 /// /// 服务器返回的应答信息(包含应答码) /// private string strMsg; /// /// 服务器返回的应答信息(包含应答码) /// private string strReply; /// /// 服务器返回的应答码 /// private int iReplyCode; /// /// 进行控制连接的socket /// private Socket socketControl; /// /// 传输模式 /// private TransferType trType; /// /// 接收和发送数据的缓冲区 /// private static int BLOCK_SIZE = Int16.MaxValue; Byte[] buffer = new Byte[BLOCK_SIZE]; /// /// 编码方式(为防止出现中文乱码采用 GB2312编码方式) /// Encoding GB2312 = Encoding.Default ;//Encoding.GetEncoding("gb2312"); #endregion #region 内部函数 /// /// 将一行应答字符串记录在strReply和strMsg /// 应答码记录在iReplyCode /// private void ReadReply() { strMsg = ""; strReply = ReadLine(); iReplyCode = Int32.Parse(strReply.Substring(0, 3)); } /// /// 建立进行数据连接的socket /// /// 数据连接socket private Socket CreateDataSocket() { SendCommand("PASV"); if (iReplyCode != 227) { throw new IOException(strReply.Substring(4)); } int index1 = strReply.IndexOf('('); int index2 = strReply.IndexOf(')'); string ipData = strReply.Substring(index1 + 1, index2 - index1 - 1); int[] parts = new int[6]; int len = ipData.Length; int partCount = 0; string buf = ""; for (int i = 0; i < len && partCount <= 6; i++) { char ch = Char.Parse(ipData.Substring(i, 1)); if (Char.IsDigit(ch)) buf += ch; else if (ch != ',') { throw new IOException("Malformed PASV strReply: " + strReply); } if (ch == ',' || i + 1 == len) { try { parts[partCount++] = Int32.Parse(buf); buf = ""; } catch (Exception) { throw new IOException("Malformed PASV strReply: " + strReply); } } } string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3]; int port = (parts[4] << 8) + parts[5]; Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ipAddress), port); try { s.Connect(ep); } catch (Exception) { throw new IOException("无法连接服务器"); } return s; } /// /// 关闭socket连接(用于登录以前) /// private void CloseSocketConnect() { if (socketControl != null) { socketControl.Close(); socketControl = null; } bConnected = false; } /// /// 读取Socket返回的所有字符串 /// /// 包含应答码的字符串行 private string ReadLine() { while (true) { int iBytes = socketControl.Receive(buffer, buffer.Length, 0); strMsg += GB2312.GetString(buffer, 0, iBytes); if (iBytes < buffer.Length) { break; } } char[] seperator = { '
' }; string[] mess = strMsg.Split(seperator); if (strMsg.Length > 2) { strMsg = mess[mess.Length - 2]; //seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串, //但也会分配为空字符串给后面(也是最后一个)字符串数组, //所以最后一个mess是没用的空字符串 //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格 } else { strMsg = mess[0]; } if (!strMsg.Substring(3, 1).Equals(" "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串) { return ReadLine(); } return strMsg; } /// /// 发送命令并获取应答码和最后一行应答字符串 /// /// 命令 private void SendCommand(String strCommand) { Byte[] cmdBytes = GB2312.GetBytes((strCommand + "\r
").ToCharArray()); socketControl.Send(cmdBytes, cmdBytes.Length, 0); ReadReply(); } #endregion } }

⑥ 这个FTP限制单线程100/k下载怎么设置啊,有高手吗教教

在下载软件里把下载速度为100k以下就可以了,把线程设置为单线程,一次开一个下载任务就可以 了。

麻烦采纳,谢谢!

⑦ 什么叫单线程下载

单线程下载
单线程下载
如果下载东西,你另存为下载,就是单程下载,如果用网际快车等软件,把东西分成五块同时下载,就叫五线程下载。当然,网际快车也可以单线程,即把东西设为一块下载。
当鼠标右键点击下载连接,用影音传送带时,出现“添加新的下载任务”页面,看到下方“快数”栏了吗,设“1”为单线程,设“2”为双线程,如此类推。
用快车下载时,出现“添加新的下载任务”页面,看到中部“文件分成
同时下载”栏了吗,设“1”为单线程,设“2”为双线程。
简单点讲吧,如果下载东西,你另存为下载,就是单程下载,如果用网际快车等软件,把东西分成五块同时下载,就叫五线程下载。当然,网际快车也可以单线程,即把东西设为一块下载。
将要下载的数据直接通过单一的,唯一的信道或媒介传输就是单线程下载。
将要下载的数据,划分为多个数据快后,按照一定的网络传输协议,分别通过单一的,唯一的信道或媒介,传输到你的机器就是多线程下载。

⑧ 如何设置多线程FTP下载

FlashfXP只能单线程下载,可以先用FlashfXP登录FTP站点,选中你要下载的文件,右击鼠标,在出现的菜单上选择:“复制URL(Ctrl+U)”,FlashfXP会提示:“是否复制用户名及密码?”,选择“是”,然后打开迅雷,点“新建(Ctrl+N)”下载任务,在出现的界面上边:“网址(URL)”里面(Ctrl+V)填上刚刚粘贴的信息,这样迅雷就可以从你的FTP站点多线程下载文件了,而且你可以同时下载不同的文件,也是多线程的。当然,万一你的FTP站点是限制单线程下载的话,为了充分利用带宽,就只好同时下载其他文件来提高效率。万一你的FTP站点是限制每个IP只能单线程下载一份文件,这个办法可能就无能为力了。希望能帮到你,呵呵~~

⑨ 求助:FTP怎样才算是单线程下载

网际快车是多线程。单线程顾名思义是只用一条“线”下载,而网际快车等可以把文件分成几部分同时下载。FTP我曾经同时打开5个文件下载,且速度都在50kb/s以上。当然要对软件进行设置。

⑩ 关于如何实现FTP上传或者下载带进度和速率的实现方法

在这里需要说明的是,该方式是通过其他代码进行改进的。 首先我们需要定义一个委托,用来实现传输过程中传递文件的总数,已完成的字节数和速度,方便客户端界面上调用。 public delegate void TransferProcess(long total,long finished,double speed); 调用代码就不举例了 接下来我们建立一个FTPClient类,该类基于socket和FTP协议实现了连接FTP服务,建立目录,上传文件,下载文件等主要方法。结构如下: 需要注意的是,我们需要定一个事件event TransferProcess OnTransferProcess;该事件在实例化FTPClient之后需要调用,这个事件对实现进度条和速率是非常重要的。为了实现速率我们还需要定义个公开的成员startTime(开始时间)。我们现在主要是看一下如何上传的。 /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { //连接服务器 if (!bConnected) { Connect(); } UpdateStatus = true; //建立socket连接 Socket socketData = CreateDataSocket(); //向FTP服务器发生存储命令 SendCommand("STOR " + Path.GetFileName(strFileName)); //如何服务器返回的信息不是我们所需要的,就抛出异常 if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4)); } //建立本地文件的数据流 FileStream input = new FileStream(strFileName, FileMode.Open); int iBytes = 0; long total = input.Length;//该成员主要记录文件的总字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 long finished = 0;//该成员主要记录已经传输完成的字节数,注意这里使用长整型,是为了突破只能传输2G左右的文件的限制 double speed = 0;//记录传输的速率 while ((iBytes = input.Read(buffer, 0, buffer.Length)) > 0)//循环从本地数据流中读取数据到缓冲区 { //Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0);//将缓冲区的数据发送到FTP服务器 DateTime endTime = DateTime.Now;//每次发送数据的结束时间 TimeSpan ts = endTime - startTime;//计算每次发送数据的时间间隔 finished += iBytes;//计算完成的字节数. Console.WriteLine(ts.Milliseconds); //计算速率,注意finished是字节,所以需要换算冲K字节 if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } //这里是必不可少的,否则你无法实现进度条 //如果传输进度事件被实例化,而且从本地数据流中读取数据不是空的并完成的字节数也不为空的话,则实现委托. if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close();//当传输完成之后需要关闭数据流,以便下次访问. if (socketData.Connected) { socketData.Close();//关闭当前的socket } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } 上面代码中注释写得比较详细,这里就不再一一讲解了,关于下载中实现进度条和速率的问题可以参考以上代码进行修改. 完整的代码如下: using System; using System.net; using System.IO; using System.Text; using System.net.Sockets; namespace MMSEncoder { public delegate void TransferProcess(long total,long finished,double speed); /// /// FTP Client /// public class FTPClient { public event TransferProcess OnTransferProcess; public bool UpdateStatus = true; public DateTime startTime; private bool IsAbortConnect = false; #region 构造函数 /// /// 缺省构造函数 /// public FTPClient() { strRemoteHost = ""; strRemotePath = ""; strRemoteUser = ""; strRemotePass = ""; strRemotePort = 21; bConnected = false; } /// /// 构造函数 /// /// FTP服务器IP地址 /// 当前服务器目录 /// 登录用户账号 /// 登录用户密码 /// FTP服务器端口 public FTPClient(string remoteHost, string remotePath, string remoteUser, string remotePass, int remotePort) { strRemoteHost = remoteHost; strRemotePath = remotePath; strRemoteUser = remoteUser; strRemotePass = remotePass; strRemotePort = remotePort; Connect(); } #endregion #region 登陆字段、属性 /// /// FTP服务器IP地址 /// private string strRemoteHost; public string RemoteHost { get { return strRemoteHost; } set { strRemoteHost = value; } } /// /// FTP服务器端口 /// private int strRemotePort; public int RemotePort { get { return strRemotePort; } set { strRemotePort = value; } } /// /// 当前服务器目录 /// private string strRemotePath; public string RemotePath { get { return strRemotePath; } set { strRemotePath = value; } } /// /// 登录用户账号 /// private string strRemoteUser; public string RemoteUser { set { strRemoteUser = value; } } /// /// 用户登录密码 /// private string strRemotePass; public string RemotePass { set { strRemotePass = value; } } /// /// 是否登录 /// private Boolean bConnected; public bool Connected { get { return bConnected; } } #endregion #region 链接 /// /// 建立连接 /// public void Connect() { //if (IsAbortConnect) throw new IOException("用户强制终止了FTP"); socketControl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ep = new IPEndPoint(IPAddress.Parse(RemoteHost), strRemotePort); // 链接 try { socketControl.Connect(ep); } catch (Exception) { throw new IOException("无法连接到远程服务器!"); } // 获取应答码 ReadReply(); if (iReplyCode != 220) { DisConnect(); throw new IOException(strReply.Substring(4)); } // 登陆 SendCommand("USER " + strRemoteUser); if (!(iReplyCode == 331 || iReplyCode == 230)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } if (iReplyCode != 230) { SendCommand("PASS " + strRemotePass); if (!(iReplyCode == 230 || iReplyCode == 202)) { CloseSocketConnect();//关闭连接 throw new IOException(strReply.Substring(4)); } } bConnected = true; // 切换到初始目录 if (!string.IsNullOrEmpty(strRemotePath)) { ChDir(strRemotePath); } } /// /// 关闭连接 /// public void DisConnect() { if (socketControl != null) { SendCommand("QUIT"); } CloseSocketConnect(); } public void AbortConnect() { if (socketControl != null) { SendCommand("ABOR"); } IsAbortConnect = true; //CloseSocketConnect(); } #endregion #region 传输模式 /// /// 传输模式:二进制类型、ASCII类型 /// public enum TransferType { Binary, ASCII }; /// /// 设置传输模式 /// /// 传输模式 public void SetTransferType(TransferType ttType) { if (ttType == TransferType.Binary) { SendCommand("TYPE I");//binary类型传输 } else { SendCommand("TYPE A");//ASCII类型传输 } if (iReplyCode != 200) { throw new IOException(strReply.Substring(4)); } else { trType = ttType; } } /// /// 获得传输模式 /// /// 传输模式 public TransferType GetTransferType() { return trType; } #endregion #region 文件操作 /// /// 获得文件列表 /// /// 文件名的匹配字符串 /// public string[] Dir(string strMask) { // 建立链接 if (!bConnected) { Connect(); } //建立进行数据连接的socket Socket socketData = CreateDataSocket(); //传送命令 SendCommand("NLST " + strMask); //分析应答代码 if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226)) { throw new IOException(strReply.Substring(4)); } //获得结果 strMsg = ""; while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); strMsg += GB2312.GetString(buffer, 0, iBytes); if (iBytes < buffer.Length) { break; } } char[] seperator = { '\n' }; string[] strsFileList = strMsg.Split(seperator); socketData.Close();//数据socket关闭时也会有返回码 if (iReplyCode != 226) { ReadReply(); if (iReplyCode != 226) { throw new IOException(strReply.Substring(4)); } } return strsFileList; } /// /// 获取文件大小 /// /// 文件名 /// 文件大小 public long GetFileSize(string strFileName) { if (!bConnected) { Connect(); } SendCommand("SIZE " + Path.GetFileName(strFileName)); long lSize = 0; if (iReplyCode == 213) { lSize = Int64.Parse(strReply.Substring(4)); } else { throw new IOException(strReply.Substring(4)); } return lSize; } /// /// 删除 /// /// 待删除文件名 public void Delete(string strFileName) { if (!bConnected) { Connect(); } SendCommand("DELE " + strFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件) /// /// 旧文件名 /// 新文件名 public void Rename(string strOldFileName, string strNewFileName) { if (!bConnected) { Connect(); } SendCommand("RNFR " + strOldFileName); if (iReplyCode != 350) { throw new IOException(strReply.Substring(4)); } // 如果新文件名与原有文件重名,将覆盖原有文件 SendCommand("RNTO " + strNewFileName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } #endregion #region 上传和下载 /// /// 下载一批文件 /// /// 文件名的匹配字符串 /// 本地目录(不得以\结束) public void Get(string strFileNameMask, string strFolder) { if (!bConnected) { Connect(); } string[] strFiles = Dir(strFileNameMask); foreach (string strFile in strFiles) { if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串 { if (strFile.LastIndexOf(".") > -1) { Get(strFile.Replace("\r", ""), strFolder, strFile.Replace("\r", "")); } } } } /// /// 下载一个文件 /// /// 要下载的文件名 /// 本地目录(不得以\结束) /// 保存在本地时的文件名 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName) { if (!bConnected) { Connect(); } SetTransferType(TransferType.Binary); if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName; } if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName); st.Close(); } FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create); Socket socketData = CreateDataSocket(); SendCommand("RETR " + strRemoteFileName); if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4)); } while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0); output.Write(buffer, 0, iBytes); if (iBytes 0) { Console.WriteLine(startTime.ToString()); socketData.Send(buffer, iBytes, 0); DateTime endTime = DateTime.Now; TimeSpan ts = endTime - startTime; finished += iBytes; Console.WriteLine(ts.Milliseconds); if (ts.Milliseconds > 0) { speed = (double)(finished / ts.TotalMilliseconds); speed = Math.Round(speed * 1000 / 1024, 2); } if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed); } } UpdateStatus = false; finished = 0; input.Close(); if (socketData.Connected) { socketData.Close(); } if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply(); if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = false; throw new IOException(strReply.Substring(4)); } } } #endregion #region 目录操作 /// /// 创建目录 /// /// 目录名 public void MkDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("MKD " + strDirName); if (iReplyCode != 257) { throw new IOException(strReply.Substring(4)); } } /// /// 删除目录 /// /// 目录名 public void RmDir(string strDirName) { if (!bConnected) { Connect(); } SendCommand("RMD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } } /// /// 改变目录 /// /// 新的工作目录名 public void ChDir(string strDirName) { if (strDirName.Equals(".") || strDirName.Equals("")) { return; } if (!bConnected) { Connect(); } SendCommand("CWD " + strDirName); if (iReplyCode != 250) { throw new IOException(strReply.Substring(4)); } this.strRemotePath = strDirName; } #endregion #region 内部变量 /// /// 服务器返回的应答信息(包含应答码) /// private string strMsg; /// /// 服务器返回的应答信息(包含应答码) /// private string strReply; /// /// 服务器返回的应答码 /// private int iReplyCode; /// /// 进行控制连接的socket /// private Socket socketControl; /// /// 传输模式 /// private TransferType trType; /// /// 接收和发送数据的缓冲区 /// private static int BLOCK_SIZE = Int16.MaxValue; Byte[] buffer = new Byte[BLOCK_SIZE]; /// /// 编码方式(为防止出现中文乱码采用 GB2312编码方式) /// Encoding GB2312 = Encoding.Default ;//Encoding.GetEncoding("gb2312"); #endregion #region 内部函数 /// /// 将一行应答字符串记录在strReply和strMsg /// 应答码记录在iReplyCode /// private void ReadReply() { strMsg = ""; strReply = ReadLine(); iReplyCode = Int32.Parse(strReply.Substring(0, 3)); } /// /// 建立进行数据连接的socket /// /// 数据连接socket private Socket CreateDataSocket() { SendCommand("PASV"); if (iReplyCode != 227) { throw new IOException(strReply.Substring(4)); } int index1 = strReply.IndexOf('('); int index2 = strReply.IndexOf(')'); string ipData = strReply.Substring(index1 + 1, index2 - index1 - 1); int[] parts = new int[6]; int len = ipData.Length; int partCount = 0; string buf = ""; for (int i = 0; i < len && partCount