其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

用Delphi实现WinSocket高级应用


发布日期:2023年06月26日
 
用Delphi实现WinSocket高级应用

Socket通信在Windows 中是排队的形式由操作系统处理而且接收方和发送方相互协同工作否则就会造成数据丢失因此不能用类似于for 语句的循环来实现对多组数据的发送更不能用循环语句来接收数据比如你可以用for 语句来实型若干文件的复制这很普遍也很正常但在 Socket编程以及大多数网络应用编程中都是行不通的因为网络通信的基本方式是请求和应答另外和所有的通信编程一样Socket编程也遵循数据分包传送这一基本规则也就是说在 Socket编程中每次发送和接收一个包以保证数据传输的安全性和稳定性同时也不至于过多地占用系统资源

对于ClientSocket组件从字面上就可以看出它用于请求方也就是说它的动作是主动地建立连接显然ServerSocket组件用于响应方它的动作是侦听以及被动接受连接

组件ClientSocket的属性是相对静态的它和ServerSocket之间只是连接和断开的关系并且仅当ServerSocket对其接受才表示建立连接

组件ServerSocket的属性是动态的伴随着一个新的ClientSocket与之建立连接的同时就会产生一个新的Socket与该ClientSocket对应保持单独的连接进行单独的通信因此在同一个 ServerSocket中可以与多个ClientSocket保持同时连接和各自独立的通信ServerSocket的属性 SocketActiveConnections用于表示客户端连接的数量属性SocketConnections[Index] 则用于访问单个与ClientSocket连接的Socket

正是这样的结构才使得WinSocket 技术能够稳定实现一个服务程序向多个客户端提供服务

在独立的ClientSocket中属性SocketData 是一个指针缺省值是nil 在ServerSocket的每个独立的SocketConnections[Index]中 属性Data也是一个指针缺省值是nil 因此可以通过该指针建立并保存各自独立的相关信息用于实现各自独立的通信而在ClientSocket的事件 OnRead中调用方法传递的Socket值就是响应该事件的对象属性ClientSocketSocket 同样在 ServerSocket的事件OnClientRead中调用方法传递的参数Socket就是对应于当前发送数据客户端的唯一的Socket连接即ServerSocketSocketConnections[Index]这样就能够对不同的连接分得清清楚楚明明白白

首先介绍实例程序的设计思想上传文件的过程是这样的(这里的C和S分别代表客户端和服务器端)

C请求上传文件

S准备就绪可以接收

C需要上传的文件信息

S收到文件信息

C第一个包

S收到第一个包创建文件开始写数据

C中间的包

S收到中间的包继续写数据

C发送最后一个包关闭文件

S收到最后一个包写数据关闭文件

下载文件的过程是这样的

C请求下载文件

S准备就绪可以下载

C需要下载的文件信息(文件名)

S反馈文件信息(文件大小)

C准备就绪可以接收数据

S第一个包

C收到第一个包创建文件开始写数据

S中间的包

C收到中间的包继续写数据

S发送最后一个包关闭文件

C收到最后一个包写数据关闭文件下载成功

S下载成功

其中发送中间的包和收到中间的包根据包的数量可以重复不难看出上面的两个过程是典型的你一句我一句的应答方式

下面是客户端应用程序和服务器端应用程序的结构客户端应用程序包括

ClientDPR

uClientPAS(DFM)(一个ClientSocket组件一个按钮一个标签一个进度条)

uClientMainPAS(DFM)(用于选择文件的一组控件和一个Edit控件三个按钮)

uSocketCommonPAS

服务器端应用程序包括

ServerDPR

uServerPAS(DFM)(一个ServerSocket组件一个Memo控件两个按钮)

uSocketCommonPAS

其中单元uSocketCommon 中包括了Socket编程的主要代码是客户端应用程序和服务器端应用程序都需要的

结合本例可以对Delphi中的WinSocket编程作如下总结

◆ 数据收发是通过会话建立和撤消的

◆ 客户端是主动连接服务程序是被动连接

◆ 每次收发的数据包其容量是有限的应当在设计时充分考虑

◆ 一个ClientSocket只能建立一个与ServerSocket的连接

◆ 一个ServerSocket可以建立多个与ClientSocket的连接

◆ 每一对连接都有唯一用于该连接的一对(两个)Socket可以通过Data属性进行标记区分

◆ 不要对无效的数据包进行响应否则可能会导致服务程序死锁

◆ 可以在传送的包中包含身份验证信息以确认是有效的数据

               

上一篇:Delphi 编程技巧常见实例问答

下一篇:放置任意的文件到Delphi的EXE文件里面