电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 在线教程-> .NET
.NET1.1开发FTP客户端-.NET教程,.NET Framework
作者:网友供稿 点击:13
  西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!虚拟主机可在线rar解压,自动数据恢复设置虚拟目录等.虚拟主机免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:[1] 
前面我的一篇文章提到使用cuteftp的ftp引擎制作.net的ftp上传客户端,但是这是个很郁闷的事情,首先,需要在注册表中注册这个com,cuteftp的官方站提供了一段注册表写法的文章,这还好说。最关键的是,在使用这个组建的时候还需要注册产品。不会有任何人希望用户在用软件的时候却还要注册别的公司的产品先。

前面之所以写采用cuteftp的引擎做客户端主要是为了方便,在一台已经安装cuteftp的pc上使用还是很方便的,但是我们还是希望开发独立的软件。

实际上采用ftp进行文件传输在搞清楚ftp命令和数据连接方式后做起来也不是很难,毕竟ftp是一个公共的协议。

以下是本人写的一个简单的示例,其中的功能只有上传文件,工作模式基本说明了ftp的原理,很容易从例子中推敲出其他ftp的功能。  在近几天的blog文章中将陆续推出一些资料信息。

另外,.net2.0中在system.net名称空间下已经封装了ftp的几个类,可以直接使用,非常方面,但是考虑到客户端对.net的兼容问题,我还是觉得采用1.1的比较好,虽然费事,但也灵活。

using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.net.sockets;
using system.io;
 
namespace ftpupload
{
     ///<summary>
     /// main 的摘要说明。
     ///
     ///存在的问题
     ///1.中文文件名 √
     ///2.文件分批读取 √
     ///3.进度显示
     ///4.扩展到控件中
     ///</summary>
     public class mainform : system.windows.forms.form
     {
         private system.windows.forms.textbox msg;
         private system.windows.forms.button commbtn;
         private system.windows.forms.button pathbtn;
         private system.windows.forms.openfiledialog openpath;
         private system.windows.forms.textbox path;
 
         private tcpclient tcp;
         private networkstream ns;
         private system.windows.forms.label process;
 
         ///<summary>
         ///必需的设计器变量。
         ///</summary>
         private system.componentmodel.container components = null;
 
         public mainform()
         {
              //
              // windows 窗体设计器支持所必需的
              //
              initializecomponent();
 
              //
              // todo: 在 initializecomponent 调用后添加任何构造函数代码
              //
         }
 
         ///<summary>
         ///清理所有正在使用的资源。
         ///</summary>
         protected override void dispose( bool disposing )
         {
              if( disposing )
              {
                   if(components != null)
                   {
                       components.dispose();
                   }
              }
              base.dispose( disposing );
         }
        
         ///<summary>
         ///应用程序的主入口点。
         ///</summary>
         [stathread]
         static void main()
         {
              application.run(new mainform());
         }
 
         #region windows 窗体设计器生成的代码
         ///<summary>
         ///设计器支持所需的方法 - 不要使用代码编辑器修改
         ///此方法的内容。
         ///</summary>
         private void initializecomponent()
         {
              this.msg = new system.windows.forms.textbox();
              this.path = new system.windows.forms.textbox();
              this.commbtn = new system.windows.forms.button();
              this.pathbtn = new system.windows.forms.button();
              this.openpath = new system.windows.forms.openfiledialog();
              this.process = new system.windows.forms.label();
              this.suspendlayout();
              //
              // msg
              //
              this.msg.location = new system.drawing.point(8, 152);
              this.msg.multiline = true;
              this.msg.name = "msg";
              this.msg.size = new system.drawing.size(552, 192);
              this.msg.tabindex = 3;
              this.msg.text = "";
              //
              // path
              //
              this.path.location = new system.drawing.point(8, 8);
              this.path.name = "path";
              this.path.size = new system.drawing.size(440, 21);
              this.path.tabindex = 4;
              this.path.text = "";
              //
              // commbtn
              //
              this.commbtn.location = new system.drawing.point(232, 48);
              this.commbtn.name = "commbtn";
              this.commbtn.tabindex = 5;
              this.commbtn.text = "post";
              this.commbtn.click += new system.eventhandler(this.commbtn_click);
              //
              // pathbtn
              //
              this.pathbtn.location = new system.drawing.point(464, 8);
              this.pathbtn.name = "pathbtn";
              this.pathbtn.tabindex = 6;
              this.pathbtn.text = "浏览…";
              this.pathbtn.click += new system.eventhandler(this.pathbtn_click);
              //
              // openpath
              //
              this.openpath.fileok += new system.componentmodel.canceleventhandler(this.openpath_fileok);
              //
              // process
              //
              this.process.location = new system.drawing.point(176, 112);
              this.process.name = "process";
              this.process.size = new system.drawing.size(248, 23);
              this.process.tabindex = 7;
              //
              // mainform
              //
              this.autoscalebasesize = new system.drawing.size(6, 14);
              this.clientsize = new system.drawing.size(568, 358);
              this.controls.add(this.process);
              this.controls.add(this.pathbtn);
              this.controls.add(this.commbtn);
              this.controls.add(this.path);
              this.controls.add(this.msg);
              this.name = "mainform";
              this.text = "main";
              this.load += new system.eventhandler(this.mainform_load);
              this.resumelayout(false);
 
         }
         #endregion
        
         private void mainform_load(object sender, system.eventargs e)
         {
             
              tcp = new tcpclient("192.168.1.88",21);
             
 
              //输入用户名
              writenetworkstream(ref ns,"user anonymous");
 
              msg.text += readnetworkstream(ref ns);
 
              //输入密码
              writenetworkstream(ref ns,"pass ");
 
              msg.text += readnetworkstream(ref ns);
         }
 
         private void pathbtn_click(object sender, system.eventargs e)
         {
              openpath.showdialog();
         }
 
         private void openpath_fileok(object sender, system.componentmodel.canceleventargs e)
         {
              path.text = openpath.filename;
         }
 
         private void commbtn_click(object sender, system.eventargs e)
         {
 
              //刷新服务器当前目录
              writenetworkstream(ref ns,"cwd /");
 
              msg.text+=readnetworkstream(ref ns);
             
              //命令服务器数据模式为被动模式
              writenetworkstream(ref ns,"pasv");
 
 
              //获取服务器pasv被动模式打开的数据连接的ip和端口信息
              string str = readnetworkstream(ref ns);
 
              msg.text+=str;
 
 
              //请求上传文件,此处将命令转换为中文编码的字节数组以支持中文文件名
              writenetworkstreamchs(ref ns,"stor "+filename(path.text.trim()));
 
              //组合ip和端口
              str =str.substring(str.indexof("(")+1,str.indexof(")")-str.indexof("(")-1);
 
              string ip = str.split(,)[0]+"."+str.split(,)[1]+"."+str.split(,)[2]+"."+str.split(,)[3];
             
              int port = int.parse(str.split(,)[4])*256+int.parse(str.split(,)[5]);
 
 
              //获取文件流
              filestream fs = file.openread(path.text.trim());
 
              //定义一个8字节数组做为缓冲区
              byte[] b = new byte[8];
 
              //建立数据传输的tcp连接
              tcpclient tcp2 = new tcpclient(ip,port);
             
              //建立该连接的网络流
              networkstream ns2 = tcp2.getstream();
             
              //每8字节读取文件流中数据到网络流中,并写入到基础存储设备,采用这个方式避免了由于一次性读取大数据量到内存中造成客户机内存使用过量。
              while(fs.read(b,0,b.length)>0)
              {
                   //建立数据的tcp连接并将文件流的内容写入到网络流
                   ns2.write(b,0,b.length);   
        
                   ns2.flush();
 
              }
 
             
             
              //关闭所用的连接
              fs.close();
 
              ns2.close();
 
              tcp2.close();
                         
 
              msg.text += readnetworkstream(ref ns);
              msg.text += readnetworkstream(ref ns);
 
             
         }
 
         #region //功能函数和方法
        
         ///<summary>
         /// ascii编码的命令请求
         ///</summary>
         ///<param name="ns">命令传输网络流</param>
         ///<param name="comm">命令字符串</param>
         ///<returns></returns>
         protected string writenetworkstream(ref networkstream ns,string comm)
         {
 
              ns = tcp.getstream();
 
              byte[] b = new byte[1024];
 
              b = system.text.encoding.ascii.getbytes(comm+"\r\n");
 
              ns.write(b,0,b.length);
 
              ns.flush();
 
              return string.empty;
         }
 
         ///<summary>
         ///中文编码方式的命令请求
         ///</summary>
         ///<param name="ns">命令传输网络流</param>
         ///<param name="comm">命令字符串</param>
         ///<returns></returns>
         protected string writenetworkstreamchs(ref networkstream ns,string comm)
         {
              ns = tcp.getstream();
 
              byte[] b = new byte[1024];
 
              //将命令以中文编码,以支持中文命令参数
              b = system.text.encoding.getencoding("gb2312").getbytes(comm+"\r\n");
 
              ns.write(b,0,b.length);
 
              ns.flush();
 
              return string.empty;
         }
 
         ///<summary>
         ///获取服务器相应字符串
         ///</summary>
         ///<param name="ns">命令传输网络流</param>
         ///<returns>服务器相应字符串</returns>
         protected string readnetworkstream(ref networkstream ns)
         {
 
              ns = tcp.getstream();
 
              byte[] b = new byte[1024];
 
              ns.read(b,0,b.length);
 
              ns.flush();
 
              return system.text.encoding.ascii.getstring(b);
         }
 
         ///<summary>
         ///获取所选文件路径的文件名
         ///</summary>
         ///<param name="path">文件路径</param>
         ///<returns>文件名</returns>
         protected string filename(string path)
         {
              return path.substring(path.lastindexof("\\")+1);
         }
 
         #endregion
 
        
     }
}
 

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关主题
文章页数:[1] 
Google
热门文章
·经典收藏之 - C++内存管理详解-.NET教程,C#语言
·Master Page 初探-.NET教程,评论及其它
·GDI+编程10个基本技巧-.NET教程,评论及其它
·VB.NET中让Textbox只能输入数字(二)-.NET教程,VB.Net语言
·stl应用小问题-.NET教程,评论及其它
·WIN32中颜色值(COLORREF)与.NET中颜色值(Color)的转换-ASP教程,系统相关
·打造自己的专业图像工具-Visual C++ 2005图像编程系列【三】-.NET教程,C#语言
·.Net中常见问题及解决方法归类-.NET教程,.NET Framework
·Lex和Yacc从入门到精通(3)--一个极其简单的lex和yacc程序-.NET教程,评论及其它
·VB下几个非常有用的函数-.NET教程,VB.Net语言

最新文章
·VC#初学入门:第一个Windows程序
·ASP.NET 2.0-选用DataSet或DataReader
·用.net 处理xmlHttp发送异步请求
·asp.net创建文件夹的IO类的问题
·asp.net 2.0 中加密web.config 文件中的配置节
·关于ASP.NET调用JavaScript的实现
·如何实现ASP.NET网站个性化
·Acegi安全系统的配置-.NET教程,评论及其它
·Spring安全系统:Acegi Security Acegi简介-.NET教程,评论及其它
·Biztalk 开发之 架构和实例的验证-.NET教程,评论及其它


 
 


版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
  打印  刷新  关闭
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 虚拟主机 | 资讯中心 | 友情链接 | 网站地图

版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2006 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86262244 86263048 86263408 86263960 86264018 86267838
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028-86264041 财务QQ:点击发送消息给对方635483282
售前咨询QQ:点击发送消息给对方2182518 点击发送消息给对方241975952 点击发送消息给对方275026793 点击发送消息给对方408235859
售后服务QQ:点击发送消息给对方17708515 点击发送消息给对方307742704 点击发送消息给对方287976517 点击发送消息给对方363783715
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号