用Delphi实现WinSocket高级应用
Socket通信在Windows 中是排队的形式由操作系统处理 而且接收方和发送方相互协同工作 否则就会造成数据丢失 因此 不能用类似于for 语句的循环来实现对多组数据的发送 更不能用循环语句来接收数据 比如 你可以用for 语句来实型若干文件的复制 这很普遍也很正常 但在 Socket编程以及大多数网络应用编程中都是行不通的 因为网络通信的基本方式是请求和应答 另外 和所有的通信编程一样 Socket编程也遵循数据分包传送这一基本规则 也就是说 在 Socket编程中 每次发送和接收一个包 以保证数据传输的安全性和稳定性 同时也不至于过多地占用系统资源
对于ClientSocket组件 从字面上就可以看出 它用于请求方 也就是说 它的动作是主动地建立连接 显然 ServerSocket组件用于响应方 它的动作是侦听以及被动接受连接
组件ClientSocket的属性是相对静态的 它和ServerSocket之间只是连接和断开的关系 并且仅当ServerSocket对其接受才表示建立连接
组件ServerSocket的属性是动态的 伴随着一个新的ClientSocket与之建立连接的同时 就会产生一个新的Socket与该ClientSocket对应 保持单独的连接 进行单独的通信 因此 在同一个 ServerSocket中 可以与多个ClientSocket保持同时连接和各自独立的通信 ServerSocket的属性 Socket ActiveConnections用于表示客户端连接的数量 属性Socket Connections[Index] 则用于访问单个与ClientSocket连接的Socket
正是这样的结构 才使得WinSocket 技术能够稳定实现一个服务程序向多个客户端提供服务
在独立的ClientSocket中 属性Socket Data 是一个指针 缺省值是nil 在ServerSocket的每个独立的Socket Connections[Index]中 属性Data也是一个指针 缺省值是nil 因此 可以通过该指针建立并保存各自独立的相关信息 用于实现各自独立的通信 而在ClientSocket的事件 OnRead中 调用方法传递的Socket值就是响应该事件的对象属性ClientSocket Socket 同样 在 ServerSocket的事件OnClientRead中 调用方法传递的参数Socket就是对应于当前发送数据客户端的唯一的Socket连接 即ServerSocket Socket Connections[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 下载成功 其中 发送中间的包和收到中间的包根据包的数量可以重复 不难看出 上面的两个过程是典型的 你一句我一句 的应答方式
下面是客户端应用程序和服务器端应用程序的结构 客户端应用程序包括
Client DPR uClient PAS( DFM)(一个ClientSocket组件 一个按钮 一个标签 一个进度条) uClientMain PAS( DFM)(用于选择文件的一组控件和一个Edit控件 三个按钮) uSocketCommon PAS 服务器端应用程序包括
Server DPR uServer PAS( DFM)(一个ServerSocket组件 一个Memo控件 两个按钮) uSocketCommon PAS 其中 单元uSocketCommon 中包括了Socket编程的主要代码 是客户端应用程序和服务器端应用程序都需要的
结合本例 可以对Delphi中的WinSocket编程作如下总结
lishixinzhi/Article/program/Delphi/201311/25007
2024-09-19 广告