在Delphi 7 中用Indy开发Socket应用程序

上传人:人*** 文档编号:489139357 上传时间:2022-09-02 格式:DOCX 页数:18 大小:266.55KB
返回 下载 相关 举报
在Delphi 7 中用Indy开发Socket应用程序_第1页
第1页 / 共18页
在Delphi 7 中用Indy开发Socket应用程序_第2页
第2页 / 共18页
在Delphi 7 中用Indy开发Socket应用程序_第3页
第3页 / 共18页
在Delphi 7 中用Indy开发Socket应用程序_第4页
第4页 / 共18页
在Delphi 7 中用Indy开发Socket应用程序_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《在Delphi 7 中用Indy开发Socket应用程序》由会员分享,可在线阅读,更多相关《在Delphi 7 中用Indy开发Socket应用程序(18页珍藏版)》请在金锄头文库上搜索。

1、在 Delphi 7 中用 Indy 开发 Socket 应用程序Delphi 7 中带有两套 TCP Socket 组件:Indy Socket 组件(IdTCPClient 和 IdTCPServer )和 Delphi 原生的 TCP Socket 组件(ClientSocket 和 ServerSocket)。但是,Borland 已宣称 ClientSocket 和 ServerSocket 组 件即将被废弃,建议用相应的Indy组件来代替。因此,笔者使用了 Indy。本文 在对Indy进行简要介绍的基础上,创建了一组简单的TCP Socket数据传输应 用来演示了 Indy 的使用

2、方法。开放源代码的 Internet 组件集Internet Direct( Indy)Internet Direct( Indy )是一组开放源代码的Internet组件,涵盖了几乎 所有流行的Internet协议。Indy用Delphi编写,被包含在Delphi 6,Kylix 1 和C+ Builder 6及以上各个版本的Borland开发环境中。Indy曾经叫做 WinShoes (双关于 WinSockWindows 的 Socket 库),是由 Chad Z. Hower领导的一群开发者构建的,可以从Indy的站点 更多的信息并下载其新版本。到笔者撰写本文时为止,Indy的最新稳定

3、版是 9.0.14, Indy 10 也进入了 Beta 测试阶段。Delphi 7中所带的是Indy 9。在其的组件面板上,一共安装有100多个Indy 组件。使用这些组件你可以开发基于各种协议的TCP客户和服务器应用程序, 并处理相关的编码和安全问题。你可以通过前缀Id来识别Indy组件。Indy是阻塞式(Blocking )的当你使用Winsock开发网络应用程序时,从Socket中读取数据或者向Socket 写入数据都是异步发生的,这样就不会阻断程序中其它代码的执行。在收到数 据时,Winsock会向应用程序发送相应的消息。这种访问方式被称作非阻塞式连 接,它要求你对事件作出响应,设置

4、状态机,并通常还需要一个等待循环。与通常的Winsock编程方法不同的是,Indy使用了阻塞式Socket调用方式。 阻塞式访问更像是文件存取。当你读取数据,或是写入数据时,读取和写入函 数将一直等到相应的操作完成后才返回。比如说,发起网络连接只需调用 Connect 方法并等待它返回,如果该方法执行成功,在结束时就直接返回,如果 未能成功执行,则会抛出相应的异常。同文件访问不同的是,Socket调用可能 会需要更长的时间,因为要读写的数据可能不会立即就能准备好(在很大程度 上依赖于网络带宽)。阻塞式 Socket 并非恶魔( Evil )长期以来,阻塞式 Socket 都遭到了毫无理由的攻击

5、。其实阻塞式 Socket 并 非如通常所说的那样可怕。这还要从Winsock的发展说起。当Socket被从Unix移植到Windows时,一个严重的问题立即就出现了。Unix 支持fork,客户程序和服务器都能够fork新的进程,并启动这些进程,从而能 够很方便地使用阻塞式Socket。而Windows 3.x既不支持fork也不支持多线程, 当使用阻塞式 Socket 时,用户界面就会被“锁住”而无法响应用户输入。为克服 Windows 3.x 的这一缺陷,微软在 Winsock 中加入了异步扩展,以使 Winsock 不会“锁住”应用程序的主线程(也是唯一的线程)。然而,这需要了 一种完

6、全不同的编程方式。于是有些人为了掩饰这一弱点,就开始强烈地诽谤 阻塞式 Socket。当 Win32 出现的时候,它能够很好地支持线程。但是既成的观念已经很难更改,并且说出去的话也无法收回,因此对阻塞式Socket的诽谤继续存在着。事实上,阻塞式Socket仍然是Unix实现Socket的唯一方式,并且它工作得 很好。阻塞式 Socket 的优点归结起来,在 Windows 上使用阻塞式 Socket 开发应用程序具有如下优点:O编程简单阻塞式Socket应用程序很容易编写。所有的用户代码都写在同一个地方,并且顺序执行。O容易向Unix移植一一由于Unix也使用阻塞式Socket,编写可移植的

7、代 码就变得比较容易。Indy就是利用这一点来实现其多平台支持而又单一源代码 的设计。O 很好地利用了线程技术阻塞式 Socket 是顺序执行的,其固有的封装 特性使得它能够很容易地使用到线程中。阻塞式 Socket 的弱点事物都具有两面性,阻塞式 Socket 也不例外。它的一个主要的缺点就是使客 户程序的用户界面“冻结”。当在程序的主线程中进行阻塞式Socket调用时, 由于要等待Socket调用完成并返回,这段时间就不能处理用户界面消息,使得 Update、Repaint 以及其它消息得不到及时响应,从而导致用户界面被“冻结”。使用 TIdAntiFreeze 对抗“冻结”Indy 使用

8、一个特殊的组件 TIdAntiFreeze 来透明地解决客户程序用户界面“冻结”的问题。TIdAntiFreeze在Indy内部定时中断对栈的调用,并在中断 期间调用Application.ProcessMessages方法处理消息,而外部的Indy调用继 续保存阻塞状态,就好像TIdAntiFreeze对象不存在一样。你只要在程序中的 任意地方添加一个TIdAntiFreeze对象,就能在客户程序中利用到阻塞式Socket 的所有优点而避开它的一些显著缺点。Indy 使用了线程技术阻塞式 Socekt 通常都采用线程技术, Indy 也是如此。从最底层开始, Indy 的设计都是线程化的。因

9、此用Indy创建服务器和客户程序跟在Unix下十分相 似,并且Delphi的快速开发环境和Indy对WinSock的良好封装使得应用程序 创建更加容易。Indy服务器模型一个典型的Unix服务器有一个或多个监听进程,它们不停地监听进入的客户 连接请求。对于每一个需要服务的客户,都fork 一个新进程来处理该客户的所 有事务。这样一个进程只处理一个客户连接,编程就变得十分容易。Indy服务器工作原理同Unix服务器十分类似,只是Windows不像Unix那样 支持fork,而是支持线程,因此Indy服务器为每一个客户连接分配一个线程。图1显示了 Indy服务器的工作原理。Indy服务器组件创建一

10、个同应用程序 主线程分离的监听线程来监听客户连接请求,对于接受的每一个客户,都创建 一个新的线程来为该客户提供服务,所有与这一客户相关的事务都由该线程来 处理。使用组件 TIdThreadMgrPool,Indy 还支持线程池。客户1线程客户n歩崔專户i违接晴敦啓戶2述樓苗叢容户證密崔IdSrver.岂匚 ive:=True;图 1 Indy 服务器工作原理线程与Indy客户程序Indy 客户端组件并未使用线程。但是在一些高级的客户程序中,程序员可以 在自定义的线程中使用Indy客户端组件,以使用户界面更加友好。简单的 Indy 应用示例下面将创建一个简单的TCP客户程序和一个简单的TCP服务

11、器来演示Indy 的基本使用方法。客户程序使用 TCP 协议同服务器连接,并向服务器发送用户 所输入数据。服务器支持两条命令:DATA和QUIT。在DATA命令后跟随要发送 的数据,并用空格将命令字DATA和数据分隔开。表单布局建立一个项目组,添加一个客户程序项目和一个服务器项目。客户程序和服 务器程序的表单布局如同2和图3所示。客户程序表单上放置了 TldTCPClient 组件,服务器程序表单上放置了 TIdTCPServer组件。为防止客户程序“冻结”, 还在其表单上放置TIdAntiFreeze组件。客户程序和服务器程序的表单上都放置有TListBox组件,用来显示通信记 录。图2简单

12、的TCP客户程序表单记录启动端口 :6060退出空丄接收到数据停止(1)图3简单的TCP服务器程序表单客户程序代码客户程序片断如代码列表1 所示。代码列表 1procedure TFormMain.BtnConnectClick(Sender: TObject); beginIdTCPClient.Host := EdtHost.Text;IdTCPClient.Port := StrToInt(EdtPort.Text);LbLog.Items.AddC 正在连接+ EdtHost.Text + .);with IdTCPClient dobegintryConnect(5000);tryL

13、bLog.Items.Add(ReadLn();BtnConnect.Enabled := False;BtnSend.Enabled := True;BtnDisconnect.Enabled := True;exceptLbLog.Items.AddC远程主机无响应!);IdTCPClient.Disconnect();end;/end tryexceptLbLog.Items.AddC 无法建立到+ EdtHost.Text + 的连接!);end;/end tryend;/end withend;procedure TFormMain.BtnSendClick(Sender: TObj

14、ect);beginLbLog.Items.Add(DATA + EdtData.Text);with IdTCPClient dobegintryWriteLn(DATA + EdtData.Text);LbLog.Items.Add(ReadLn()exceptLbLog.Items.AddC 发送数据失败!);IdTCPClient.Disconnect();LbLog.Items.AddC 同主机+ EdtHost.Text + 的连接已断开!);BtnConnect.Enabled := True;BtnSend.Enabled := False;BtnDisconnect.Enab

15、led := False;end;/end tryend;/end withend;procedure TFormMain.BtnDisconnectClick(Sender: TObject);varReceived: string;beginLbLog.Items.Add(QUIT);tryIdTCPClient.WriteLn(QUIT);finallyIdTCPClient.Disconnect();LbLog.Items.AddC 同主机+ EdtHost.Text + 的连接已断开!);BtnConnect.Enabled := True;BtnSend.Enabled := False;BtnDisconnect.Enabled := False;end;/end tryend;在“连接”按钮事件响应过程中,首先根据用户输入设置IdTCPClient的主 机和端口,并调用 IdTCPClient 的 Connect 方法向服务器发出连接请求。然后 调用ReadLn方法读取服务器应答数据。在“发送”按钮事件响应过程中,调用WriteL

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 建筑资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号