Delphi实例分析:远程传输数据和文件

[摘要] 在Windows操作系统的平台上,WinSock是首选的网络编程接口,用于在网络上传输数据和交换信息,它构成了Windows操作系统进行网络编程的基础。对于编写网络应用程序来说,WinSock是一门非常重要的并且必须掌握的知识,虽然现在有很多的工具如FTP程序可以在网络上传输数据和文件,但是通过WinSock编程具有更大的灵活性,因为它不需要关心网络连接的细节问题。
[关键字] Delphi Windows 远程传输
【eNet硅谷动力专稿】在Windows操作系统的平台上,WinSock是首选的网络编程接口,用于在网络上传输数据和交换信息,它构成了Windows操作系统进行网络编程的基础。对于编写网络应用程序来说,WinSock是一门非常重要的并且必须掌握的知识,虽然现在有很多的工具如FTP程序可以在网络上传输数据和文件,但是通过WinSock编程具有更大的灵活性,因为它不需要关心网络连接的细节问题。然而用WinSock编程却相当复杂,但是在Delphi中我们并不需要直接与WinSock的API函数打交道,因在Delphi中的TClientSocket组件和TServerSocket组件封装了WinSock的大部分API函数,使得对WinSock的编程大大简化。在网络通信协议的面向连接服务中,进行传输数据和交换信息之前,通信双方应该建立一条用于进行数据交换的“链路”,通信双方就是利用这个“链路”进行稳定可靠的数据传输,由于建立通信的双方都处于收发信息的状态,并且保证了数据传输的稳定性,所以在传输较大的文件时,具有较高的效率。而建立“链路”和断掉“链路”都需要消耗一定的时间,所以在传输较小文件时的效率是比较低的。

  在这里我们将了解winsock如何实现远程传输数据和文件。在一个局域网内不同的计算机上分别运行服务器端程序和客户端程序。服务器端运行后就启动,socket将建立侦听状态。客户端运行后,在客户端程序中填写服务器IP地址,然后单击“连接”按钮,向服务器端发出一个建立连接的请求,如图1所示。如果通客户端程序过端口成功和服务器端连接,服务器端的状态栏就会有“已和客户端连接”的提示,并准备传输文件,如图2所示。

  
delphi

  图1


  
delphi

  图2


  单击“发送”按钮,在弹出的对话框中选择一个准备发送的文件,然后客户端将文件的大小和其他信息等发送到服务器端,服务器端接受到文件的信息后通知客户端开始传送文件,文件的数据需要多次传递,服务器将文件全部接受并保存。系统运行如图3、图4所示:

  
delphi

  图3


  
delphi

  图4


  服务器端程序编写:

新建一个项目,并把一个TServerSocket组件放到Form1窗体上,Active设为True;端口Port设为2000,其它属性按默认值。服务器端程序代码如下:

  unit Unit1;

  interface

  uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

   Dialogs, StdCtrls, ScktComp, ComCtrls, DB, DBTables, XPMan;

  Const

   MP_QUERY ='1';

   MP_REFUSE ='2';

   MP_ACCEPT ='3';

   MP_NEXTWILLBEDATA ='4';

   MP_DATA ='5';

   MP_ABORT ='6';

   MP_OVER ='7';

   MP_CHAT ='8';

   MP_END ='9';

   MP_FILEPROPERTY ='0';

   iBYTEPERSEND=1024;

  type

   TForm1 = class(TForm)

  Serversocket: TServerSocket;

   Query1: TQuery;

   GroupBox1: TGroupBox;

   Memo1: TMemo;

   XPManifest1: TXPManifest;

   StatusBar1: TStatusBar;

   Button1: TButton;

   procedure serversocketClientConnect(Sender: TObject; Socket: TCustomWinSocket);

   procedure serversocketClientRead(Sender: TObject; Socket: TCustomWinSocket);

   procedure serversocketClientError(Sender: TObject; Socket: TCustomWinSocket;

   ErrorEvent: TErrorEvent; var ErrorCode: Integer);

   procedure Button1Click(Sender: TObject);

   procedure FormCreate(Sender: TObject);

  

   private

   fsRecv:TMemoryStream;

   public

   { Public declarations }

   end;

  

  var

   Form1: TForm1;

   bReadText:boolean;

  

  implementation

  

  {$R *.dfm}

  

  procedure TForm1.FormCreate(Sender: TObject);

  begin

   Serversocket.Port:=2000;//设置侦听端口为2000;

   bReadText:= true;

   Serversocket.Open;

   StatusBar1.SimpleText:=' 就绪 ';

  end;

  

  procedure TForm1.ServersocketClientConnect(Sender: TObject;

   Socket: TCustomWinSocket);

  begin

   Statusbar1.SimpleText:=' 已和IP地址为 '+Socket.RemoteAddress+' 客户端连接 ';

  end;

  

  procedure TForm1.serversocketClientRead(Sender: TObject; Socket: TCustomWinSocket);

  var

   sTemp ,existfile, newfile : string;

   bufRecv:Pointer;

   iNum:integer;

   begin

   Memo1.Lines.Add('received size :' + intToStr(Socket.ReceiveLength));

   if bReadText then

   begin

   sTemp:=Socket.ReceiveText;

   case sTemp[1] of

   MP_QUERY:

   begin

   Memo1.Lines.Add('receive MP_QUERY');

   existfile:=Copy(sTemp,2,Length(STemp)); ;

   newfile:= 'c:\Administrator\'+ExtractFileName(existfile);

   copyfile(pchar(existfile),pchar(newfile),false);

   serversocket.Socket.Connections[0].SendText(MP_ACCEPT);

  

   fsRecv := TMemoryStream.Create;

  

   serversocket.Socket.Connections[0].SendText(MP_REFUSE+'');

   end;

   MP_FILEPROPERTY:

   begin

   Memo1.Lines.Add('receive MP_FILEPROPERTY');

   serversocket.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);

   end;

   MP_NEXTWILLBEDATA:

   begin

   Memo1.Lines.Add('receive MP_NEXTWILLBEDATA');

   bReadText:=false;

   serversocket.Socket.Connections[0].SendText(MP_DATA);

   end;

   MP_END:

   begin

   Memo1.Lines.Add('receive MP_END');

   fsRecv.Free;

   bReadText:=true;

   end;

   MP_ABORT:

   begin

   Memo1.Lines.Add('receive MP_ABORT');

   fsRecv.Free;

   bReadText:=true;

   end;

   MP_CHAT:

   begin

   Memo1.Lines.Add('receive MP_CHAT');

   end;

   end;{of case}

   end

   else

   begin

   try

  

   GetMem(bufRecv, iBYTEPERSEND);

   iNum := Socket.ReceiveBuf(bufRecv^, iBYTEPERSEND);

   fsRecv.WriteBuffer(bufRecv^, iNum);

   finally

   FreeMem(bufRecv);

   end;{of try}

   bReadText:=true;

  

   if iNum = iBYTEPERSEND THEN

   begin

   serversocket.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);

   end

   else

   begin

  

   fsRecv.Free;

   serversocket.Socket.Connections[0].SendText(MP_END);

   end;

   end;

   end;

  procedure TForm1.serversocketClientError(Sender: TObject; Socket: TCustomWinSocket;

   ErrorEvent: TErrorEvent; var ErrorCode: Integer);

  begin

   Memo1.Lines.Add('ErrorCode :' + IntToStr(ErrorCode));

   ErrorCode := 0;

  end;

  

  procedure TForm1.Button1Click(Sender: TObject);

  var

   i, j: integer;

  begin

   J := serversocket.Socket.ActiveConnections;

   Memo1.Lines.Add('ActiveConnectiong is ' + inttostr(j));

  end;

  end.

  客户端程序编写:

  新建一个工程,并把一个TClientSocket组件放到Form1窗体上,Port设为2000(端口号可任意设置,要求客户端和服务器端统一),其它属性按默认值。具体客户端程序代码如下:

  unit Unit2;

  interface

  uses

   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

   Dialogs, StdCtrls, ScktComp, ComCtrls, XPMan;

  const

   MP_QUERY ='1';

   MP_REFUSE ='2';

   MP_ACCEPT ='3';

   MP_NEXTWILLBEDATA='4';

   MP_DATA ='5';

   MP_ABORT ='6';

   MP_OVER ='7';

   MP_CHAT ='8';

   MP_END ='9';

   MP_FILEPROPERTY ='0';

   iBYTEPERSEND=1024;

  

  type

   TForm1 = class(TForm)

   cs: TClientSocket;

   OpenDialog1: TOpenDialog;

   StatusBar1: TStatusBar;

   GroupBox1: TGroupBox;

   edtIPAddress: TEdit;

   Edit2: TEdit;

   btnSendFile: TButton;

   btnConnect: TButton;

   XPManifest1: TXPManifest;

   GroupBox2: TGroupBox;

   Label1: TLabel;

   edtSize: TEdit;

   Memo1: TMemo;

   procedure btnConnectClick(Sender: TObject);

   procedure btnSendFileClick(Sender: TObject);

   procedure FormCreate(Sender: TObject);

   procedure csRead(Sender: TObject; Socket: TCustomWinSocket);

   private

   fsSend:TFileStream;

   public

   { Public declarations }

   end;

  

  var

   Form1: TForm1;

  

  implementation

  

  {$R *.dfm}

  procedure TForm1.btnConnectClick(Sender: TObject);

   begin

   cs.Address := edtIPAddress.Text;

   cs.Port:=2000;

   cs.Open;

   end;

  

  procedure TForm1.btnSendFileClick(Sender: TObject);

  begin

  if OpenDialog1.Execute then

   Begin

   cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);

   end;

  end;

  

  procedure TForm1.FormCreate(Sender: TObject);

  begin

   edtipaddress.Text:='127.0.0.1';

  end;

  

  procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);

  var

   sRecv:string;

   iNum:integer;

   bufSend:pointer;

   begin

   sRecv:=Socket.ReceiveText;

   Memo1.Lines.Add('sRecv =' + sRecv);

   Case sRecv[1] of

   MP_REFUSE:ShowMessage('Faint,be refused!');

   MP_ACCEPT:begin

   Memo1.Lines.Add('MP_ACCEPT');

   fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);

   edtSize.Text:=IntToStr(fsSend.Size);

   edit2.text:='total count:'+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1);

   cs.Socket.SendText(MP_FILEPROPERTY+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1));

   fsSend.Seek(0, soFromBeginning);

   end;

   MP_NEXTWILLBEDATA:begin

   Memo1.Lines.Add('MP_NEXTWILLBEDATA');

   Socket.SendText(MP_NEXTWILLBEDATA);

   end;

   MP_DATA:

   begin

   Memo1.Lines.Add('MP_DATA');

   try

   GetMem(bufSend, iBYTEPERSEND);

   iNum := fsSend.Read(bufSend^, iBYTEPERSEND);

   cs.Socket.SendBuf(bufSend^, iNum);

   Memo1.Lines.Add('Send Buf finished');

   finally

   FreeMem(bufSend);

   end;{of try}

   end;

   MP_END:

   begin

   Memo1.Lines.Add('MP_END');

   fsSend.Free;

   end;

   MP_ABORT:begin

   Memo1.Lines.Add('MP_ABORT');

   fsSend.Free;

   end;

   end;

   end;

  end.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第1章 Delphi网络编程基础知识 1.1 TCP/IP 1.1.1 TCP/IP结构 1.1.2 应用层协议 1.1.3 传输层协议 1.1.4 网络层协议 1.1.5 RFC和标准简单服务 1.2 TCP/IP基本概念 1.2.1 IP地址 1.2.2 地址解析 1.2.3 域名系统 1.2.4 数据包的封装和分用 1.2.5 端口号 1.3 网络编程接口(Winsock API) 1.4 Winsock常用函数介绍 1.4.1 基本Socket函数 1.4.2 数据库函数 1.4.3 Winsock规范提供的扩展函数 1.5 Delphi Socket网络组件介绍 1.5.1 ClientSocket组件 1.5.2 ServerSocket组件 第2章 基本网络编程实例 2.1 获取IP地址 2.1.1 利用系统工具获得IP地址 2.1.2 使用GetHostByName函数来获取IP 2.1.3 使用WSAAsyncGetHostByName函数获取IP地址 2.1.4 多IP情况的处理 2.1.5 关于IP地址和实际的地址的区别 2.2 获取子网掩码 2.2.1 Windows NT系统中获取子网掩码 2.2.2 Window 9x系统中获取子网掩码 2.3 获取计算机名 2.3.1 获取和设置本机主机名 2.3.2 获取远程主机名称 2.4 网络连接情况检测 2.4.1 使用WinInet高级函数库函数检测网络状态 2.4.2 通过读取系统状态参数检测网络状态 2.5 获取DNS信息 2.5.1 Windows NT系统中获取DNS信息 2.5.2 Windows 9x系统中获取DNS信息 2.6 网卡信息的获取 2.6.1 使用GUID获取网卡地址 2.6.2 NetBIOS来获得MAC地址 2.6.3 使用RPC方式获得MAC地址 第3章 FTP高级编程 3.1 FTP简介 3.2 安装设置FTP服务器 3.3 使用Windows内置FTP程序 3.4 深入FTP协议 3.4.1 FTP命令大全 3.4.2 FTP工作模式 3.5 开发FTP程序的方法 3.6 API开发高级FTP客户端程序 3.6.1 建立工程项目 3.6.2 关键代码分析 3.7 开发FTP服务器 3.7.1 建立工程项目 3.7.2 关键代码分析 第4章 HTTP高级开发 4.1 HTTP协议基本知识 4.1.1 HTTP背景 4.1.2 HTTP的内容 4.1.3 消息(Message) 4.1.4 请求(Request) 4.1.5 响应(Response) 4.1.6 访问认证 4.1.7 URL编码 4.1.8 HTTP协议的应用 4.2 开发文件下载程序 4.2.1 建立工程项目 4.2.2 关键代码分析 4.2.3 技术要点分析 4.3 HTTP API高级开发 4.3.1 控件介绍 4.3.2 关键代码分析 4.3.3 关键技术分析 4.4 Web Server高级开发 4.4.1 Web Server的基本理论 4.4.2 建立工程项目 4.4.3 关键代码分析 4.4.4 Web服务器的扩充 4.5 Web代理服务器的实现 4.5.1 代理服务器介绍 4.5.2 IE中使用代理服务器设置 4.5.3 建立工程项目 4.5.4 关键代码分析 第5章 Telnet高级编程 5.1 Telnet简介 5.2 使用Windows的Telnet程序登录远程服务器 5.3 深入Telnet协议 5.3.1 NVT ASCII字符集 5.3.2 Telnet命令 5.3.3 协商选项 5.3.4 子协商选项 5.3.5 Telnet操作方式 5.4 BBS客户端高级开发 5.4.1 建立工程项目 5.4.2 关键代码分析 5.5 Telnet代理服务程序实现 5.5.1 建立工程项目与关键代码分析 第6章 E-mail协议及高级编程 6.1 SMTP及发送电子邮件 6.1.1 SMTP的模型描述 6.1.2 SMTP的会话过程 6.2 POP3与接收电子邮件 6.2.1 POP3的模型描述 6.2.2 POP3的会话过程 6.3 信件结构详述 6.3.1 RFC822信件的格式和内容 6.3.2 构造符合RFC822的信件 6.3.3 RFC822信件的语法分析 6.4 MIME编码解码与发送附件 6.4.1 RFC822的局限 6.4.2 UUENCODE编码与解码 6.4.3 MIME及其编码 6.4.4 构造MIME信件 6.4.5 MIME信件的语法分析 6.5 E-mail乱码 6.5.1 乱码的常见形式及形成原因 6.5.2 避免乱码的方法 6.6 E-mail程序开发 6.6.1 建立工程项目 6.6.2 关键代码分析 第7章 网络监控、流量统计与资源搜索 7.1 网络流量统计 7.1.1 建立工程项目 7.1.2 关键代码分析 7.2 网络连接监控 7.2.1 建立工程项目 7.2.2 关键代码分析 7.3 网络配置和统计的使用实例 7.3.1 建立工程项目 7.3.2 关键代码分析 7.4 局域网资源搜索 7.4.1 建立工程项目 7.4.2 关键代码分析 7.4.3 关键技术分析 第8章 Modem串口通信编程 8.1 Modem的基础知识 8.1.1 Modem状态 8.1.2 AT命令 8.1.3 S寄存器 8.1.4 Modem返回信息码 8.2 SPComm通信控件 8.2.1 SPComm控件的属性 8.2.2 SPComm控件的方法 8.2.3 SPComm控件的事件 8.3 Windows串口通信编程 8.3.1 Windows通信API和串口通信 8.3.2 打开和关闭串口 8.3.3 串口配置和串口属性 8.3.4 读写串口 8.3.5 通信事件 8.3.6 设备控制命令 8.4 ASCII控制字符 8.5 Modem文件传输应用实例 8.5.1 建立工程项目 8.5.2 关键代码分析 第9章 拨号网络编程 9.1 RAS客户机 9.2 建立拨号连接 9.3 使用RAS(远程访问服务) 9.3.1 用系统电话簿进行拨号 9.3.2 电话簿条目的管理 9.3.3 在程序中创建拨号连接 9.3.4 状态通知 9.4 RAS高级开发拨号程序 9.4.1 创建工程项目 9.4.2 关键代码分析 第10章 传真高级编程 10.1 传真编程的基础知识 10.1.1 T.30传真通信协议 10.1.2 HDLC信息包 10.1.3 传真字段 10.1.4 成串信息包 10.1.5 同步线路控制 10.1.6 传真的五个阶段介绍 10.2 传真Modem的分类 10.2.1 传真分类 10.2.2 一类传真Modem 10.2.3 二类传真Modem 10.3 传真会话实例描述 10.3.1 一类传真的发送实例 10.3.2 一类传真的接收实例 10.3.3 二类传真的发送实例 10.3.4 二类传真的接收实例 10.4 DIS/DCS位映像 10.4.1 向后兼容性和可扩展性 10.4.2 新的 FCF 10.4.3 最小性能集合 10.4.4 DIS/DCS信息包的逐位解释 10.5 T.4传真图像协议 10.5.1 分辨率 10.5.2 文件尺寸 10.6 传真编码 10.6.1 一维编码(改进型哈夫曼编码) 10.6.2 二维编码(READ编码) 10.6.3 编码方式综述 10.6.4 行终码 10.6.5 页编码 10.7 传真高级编程 10.7.1 创建工程项目 10.7.2 关键代码分析
Delphi是一种常用的编程语言和集成开发环境(IDE),可以用于开发各种应用程序,包括网络应用程序。在局域网内进行文件传输,特别是大文件传输,我们可以使用Delphi来实现。 在Delphi中,我们可以使用TCP/IP协议来进行文件传输。首先,我们需要创建一个服务器程序和一个客户端程序来实现文件发送和接收。 服务器程序负责监听局域网上的指定端口,等待客户端的连接请求。一旦接收到连接请求,服务器程序会创建一个新的线程来处理每个连接,并开始接受文件数据。服务器程序可以使用TIdTCPServer组件来实现。 客户端程序负责连接到服务器,并将文件数据发送服务器。客户端程序可以使用TIdTCPClient组件来实现。 在文件传输过程中,可以将大文件分成多个小块进行传输,以减少传输时间和资源占用。服务器程序和客户端程序可以通过TCP连接发送和接收这些文件块,并将它们重新组合成完整的文件。 在Delphi中,可以使用TFileStream类来读取和写入文件数据。可以使用TIdTCPStream类将文件数据发送和接收到服务器和客户端之间的TCP连接。 为了确保文件传输的可靠性,可以使用校验和或哈希算法对文件进行完整性校验。在传输过程中,可以检查接收到的文件块的校验和或哈希值,以确保它们与原始文件的值匹配。 另外,为了提高文件传输的效率,可以使用压缩算法对文件进行压缩。Delphi中有一些常见的压缩库,如Zlib、ZipForge等,可以用来压缩和解压缩文件。 总结起来,使用Delphi可以方便地实现局域网内大文件的传输。通过建立TCP连接、分块传输、完整性校验和压缩等技术,可以确保文件的安全、可靠和高效传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值