第 七 章 使 用 WinSock
从 程 序 员 的 角 度 看 W inS oc k 是 一 组 用 C 语 言 写 的 AP I 用 于 通 过 In te rn e t 进行 数 据 传 输 虽 然 现 在 有 很 多 现 成 的 工 具 如 W W W 浏 览 器 FT P 程 序 可 以 实现 在 In te rn e t上 传 输 数 据 和 文 件 但 是 通 过 W inS oc k 编 程 可 以 获 得 更 大 的 灵活 性
编 写 W inS oc k 应 用 程 序 本 来 是 很 麻 烦 的 不 过 在 C+ + Bu ild e r 3 中 您 并 不需 要 直 接 与 W inS oc k 中 的 AP I 打 交 道 因 为 C+ + Bu ild e r 3 新 增 加 了T C lie n t S oc ke t元 件 和 T S e rve r S oc ke t元 件 这 两 个 元 件 封 装 了 W in dow s 的 有 关AP I 使 得 对 W inS oc k 的 访 问 大 大 简 化
1 关 于 So ck et 的 概 述
要 通 过 In te rn e t传 输 数 据 您 至 少 需 要 一 对 S o ck et( 意 为 插 座 ) 其 中 一 个 S o ck et 在 客 户 端 另 一 个 S o ck et 在 服 务 器 端 一 旦 客 户 端 和 服 务 器 端 都 接 通 了S o ck et 客 户 端 和 服 务 器 端 就 可 以 相 互 通 信 就 好 像 墙 上 的 电 话 插 孔 一 样
用 S o ck et建 立 的 连 接 是 建 立 在 TC P / IP 协 议 基 础 上 的 同 时 也 支 持 其 它 相 关 的协 议 如 XNS DE C n e t以 及 IP X / S P X 等
C+ + Bu ild e r 3 分 别 用 T C lie n tS o c k e t 元 件 和 T S e rve r S oc k e t 元 件 来 操 纵 客 户 端
S o ck et与 服 务 器 端 S o ck et的 连 接 和 通 信 要 说 明 的 是 这 两 个 元 件 用 于 管 理服 务 器 和 客 户 的 连 接 本 身 并 不 是 S o ck et 对 象 操 纵 S o ck et 对 象 的 是T C u s to m W in S o c k e t 及 其 派 生 类 如 T C lien t W in S o ck et T S erv e r W in S o ck e t 和T S erv e r C lien t W in S o ck et等
根 据 连 接 启 动 的 方 式 以 及 本 地 S o ck et要 连 接 的 目 标 S o ck et之 间 的 连 接 可 以分 为 三 种 类 型 客 户 端 连 接 监 听 连 接 以 及 服 务 器 端 连 接
所 谓 客 户 端 连 接 是 指 由 客 户 端 的 S o ck et提 出 连 接 请 求 要 连 接 的 目 标 是 服务 器 端 的 S o ck et 为 此 客 户 端 的 S o ck et必 须 首 先 描 述 它 要 连 接 的 服 务 器 端S o ck et( 主 要 是 指 服 务 器 端 S o ck et的 地 址 和 端 口 号 ) 然 后 再 定 位 所 要 连 接 的服 务 器 端 S o ck et 找 到 以 后 就 向 服 务 器 端 S o ck et请 求 连 接 当 然 服 务 器端 的 S o ck et此 时 未 必 正 好 处 于 准 备 好 状 态 不 过 服 务 器 端 的 S o ck et会 自 动维 护 客 户 请 求 连 接 的 队 列 然 后 在 它 认 为 合 适 的 时 候 向 客 户 端 S o ck et发 出 允许 连 接 ( A cce p t) 的 信 号 这 时 客 户 端 S o ck et 与 服 务 器 端 S o ck et 的 连 接 就 建立 了
所 谓 监 听 连 接 服 务 器 端 S o ck et并 不 定 位 具 体 的 客 户 端 S o ck et 而 是 处 于 等待 连 接 的 状 态 当 服 务 器 端 S o ck et监 听 到 或 者 说 接 收 到 客 户 端 S o ck et的 连 接请 求 它 就 响 应 客 户 端 S o ck et的 请 求 建 立 一 个 新 的 S o ck et句 柄 并 与 客 户 端 连接 而 服 务 器 端 S o ck et继 续 处 于 监 听 状 态 还 可 以 接 收 其 它 客 户 端 S o ck et的连 接 请 求
所 谓 服 务 器 端 连 接 是 指 当 服 务 器 端 S o ck et接 收 到 客 户 端 S o ck et的 连 接 请 求后 就 把 服 务 器 端 S o ck et的 描 述 发 给 客 户 端 一 旦 客 户 端 确 认 了 此 描 述 连接 就 建 立 了
建 立 服 务 器 端 So ck et
把 一 个 T S e rve r S oc ke t 元 件 加 到 Fo rm 或 数 据 模 块 上 您 的 应 用 程 序 就 变 成 了一 个 TC P / IP 服 务 器 当 服 务 器 处 于 监 听 状 态 时 服 务 器 端 的 S o ck et 对 象 用T S erv e r W in S o ck e t来 操 纵 当 客 户 提 出 连 接 请 求 服 务 器 响 应 了 连 接 请 求 并建 立 了 连 接 此 时 用 T S e rve r C lie n tW inS oc ke t来 操 纵 服 务 器 端 So c k e t与 客 户 端S o ck et的 连 接
要 使 服 务 器 能 监 听 客 户 的 连 接 请 求 您 必 须 首 先 指 定 端 口 号 ( 设 置T S e rve r S oc ke t 元 件 的 Po r t 特 性 ) 当 然 如 果 服 务 器 提 供 的 是 某 些 标 准 的 服务 如 FT P H TTP F INGE R 或 T IM E 这 些 标 准 服 务 的 端 口 号 是 事 先 约 定 的也 就 是 说 您 只 要 指 定 了 服 务 类 型 ( 设 置 T S e rve r S oc ke t元 件 的 Se rv ic e 特 性 )
端 口 号 就 已 经 隐 含 确 定 了 如 果 您 同 时 设 置 了 Po r t特 性 和 Se rv ic e 特 性 C+ +
B u ild e r 3 将 忽 略 Po r t特 性
指 定 了 端 口 号 或 由 Se rv ic e 特 性 隐 含 指 定 了 端 口 号 后 您 就 可 以 调 用T S e rve r S oc ke t元 件 的 O p e n 函 数 开 始 监 听 如 果 您 在 设 计 期 把 A c tiv e 特 性 设 为T ru e 服 务 器 就 自 动 进 入 监 听 状 态 也 就 是 说 把 A c tiv e 特 性 设 为 T ru e 和 调用 O p e n 是 等 价 的
一 旦 进 入 了 监 听 状 态 您 就 可 以 通 过 T S e rve r S oc ke t元 件 的 S o ck et特 性 返 回 服务 器 端 的 S o ck et对 象 ( T S e rv e r W inS oc ke t) 并 由 此 对 象 获 得 有 关 连 接 的 信 息例 如 S o ck et 对 象 的 S o ck et H a n d le 特 性 可 以 获 得 S o ck et 的 W in dow s 句 柄 在直 接 调 用 W inS oc k 的 AP I 时 需 要 用 到 这 个 句 柄 S o ck et 对 象 的 H a nd le 特 性 可
以 访 问 从 S o ck et连 接 中 检 索 消 息 的 窗 口
服 务 器 进 入 监 听 状 态 后 当 客 户 提 出 连 接 请 求 服 务 器 就 自 动 接 受 请 求 建立 连 接 并 触 发 O n C lie n tC onne c t 事 件 此 时 服 务 器 端 S o ck et与 客 户 端 S o ck et 的 连 接 由 T s e rv e r C lie n t- W in S o c k e t 来 操 纵 T S erv e r W in S o ck e t 的 C onne c tions 特 性 可 以 返 回 一 个 数 组 该 数 组 由 服 务 器 当 前 活 动 的 连 接 ( T S e rv e r C lie n tW inS oc ke t) 组 成
如 果 要 断 开 连 接 只 要 在 服 务 器 端 调 用 C lo s e 函 数 或 者 把 A c tiv e 特 性 设 为Fa ls e 注 意 这 将 导 致 所 有 与 客 户 的 连 接 都 断 开 并 退 出 监 听 状 态 如 果在 客 户 端 调 用 C lo s e 将 只 断 开 该 客 户 与 服 务 器 的 连 接 不 影 响 其 它 客 户 的连 接
T S e rve r S oc ke t 的 直 接 上 级 是 T C us to m S e rve r S oc ke t 而 T C us to m S e rve r S o c ke t 又 是 从 T C us to m S oc ke t 继 承 下 来 的 T C us to m S oc ke t 又 是 从 T C o m pone n t 继 承下 来 的 因 此 T S e rve r S oc ke t 元 件 是 典 型 的 非 可 视 的 元 件 要 注 意 的 是
T C us to m S oc ke t 是 T S e rve r S oc ke t 元 件 的 虚 拟 基 类 您 不 能 直 接 创 建
T C us to m S oc ke t的 实 例
建 立 客 户 端 So ck et
把 一 个 T C lie n t S oc ke t 元 件 加 到 Fo rm 或 数 据 模 块 上 您 的 应 用 程 序 就 变 成 一个 TC P / IP 客 户 您 可 以 用 T C lie n tW in S o c k e t来 操 纵 客 户 端 的 S o ck et对 象
要 说 明 的 是 您 可 以 把 T S e rve r S oc ke t 元 件 和 T C lie n t S oc ke t 元 件 加 到 同 一 个
Fo rm 或 数 据 模 块 上 这 样 应 用 程 序 就 兼 具 TC P / IP 服 务 器 和 客 户 两 种 角 色
要 建 立 与 服 务 器 的 连 接 您 首 先 需 指 定 要 连 接 的 服 务 器 指 定 服 务 器 可 以有 两 种 方 式 一 是 设 置 H o s t 特 性 指 定 服 务 器 的 主 机 名 如h ttp ://w w w . w S ite . C o m 这 种 方 式 比 较 直 观 但 要 花 费 域 名 解 析 的 时 间 如果 您 不 知 道 主 机 名 或 者 您 想 节 省 域 名 解 析 的 时 间 您 可 以 设 置 A ddre s s 特性 直 接 指 定 主 机 的 IP 地 址 如 123 .197 .1 .2 这 两 种 方 式 的 效 果 是 等 价 的 但 如果 您 同 时 设 置 了 H o s t特 性 和 A ddre s s 特 性 C+ + Bu ild e r 3 将 忽 略 A ddre s s 特 性要 建 立 与 服 务 器 的 连 接 还 要 指 定 客 户 要 连 接 的 服 务 器 上 的 端 口 号 这 里也 有 两 种 方 式 一 是 直 接 设 置 Po r t特 性 指 定 端 口 号 如 1024 也 可 以 设 置 Se rv ic e 特 性 隐 含 确 定 端 口 号 如 果 您 同 时 设 置 了 Po r t特 性 和 Se rv ic e 特 性 C+ + Bu ild e r 3 将 忽 略 Po r t特 性
指 定 了 服 务 器 以 及 要 连 接 的 端 口 号 后 ( 这 称 为 在 客 户 端 描 述 服 务 器 ) 您 只 要调 用 O p e n 函 数 或 者 把 A c tiv e 特 性 设 为 T ru e 客 户 端 S o ck et就 向 服 务 器 端 S o ck et 提 出 连 接 请 求 如 果 服 务 器 此 时 处 于 监 听 状 态 就 会 自 动 接 受 请 求 并 建 立连 接
- 旦
建 立 了 与 服 务 器 的 连 接 您 就 可 以 用 T C lie n tS o c k e t元 件 的 S o ck et特 性 返回 客 户 端 的 S o ck et 对 象 ( T C lie n t W inS oc ke t) 并 由 此 对 象 获 得 有 关 连 接 的 信息 例 如 S o ck et对 象 的 S o ck et H a n d le 特 性 可 以 获 得 S o ck et的 W in dow s 句 柄如 果 您 要 直 接 调 用 W inS oc k 的 AP I 就 要 用 到 这 个 句 柄 您 还 可 以 通 过 S o ck et 对 象 的 H a nd le 特 性 访 问 从 S o ck et连 接 中 检 索 消 息 的 窗 口 您 还 可 以 用 S o ck et 对 象 的 AS y n c S ty le s 特 性 设 置 要 捕 捉 哪 些 消 息
在 客 户 端 要 断 开 连 接 很 简 单 只 要 调 用 C lo s e 函 数 此 时 服 务 器 端 将 触 发
O n C lie n tD is c onne c t事 件 而 客 户 端 将 触 发 O n D is c onne c t事 件
T C lie n t S oc ke t 元 件 的 直 接 上 级 是 T C us to m S oc ke t 而 T C us to m S oc k e t 又 是 从T C o m pone nt 继 承 下 来 的 因 此 T C lie n t S oc ke t 元 件 也 是 一 个 典 型 的 非 可 视的 元 件
怎 样 在 网 络 上 传 输 数 据
- 旦
服 务 器 端 S o ck et与 客 户 端 S o ck et之 间 建 立 了 连 接 就 可 以 通 过 In te rn e t传输 数 据 和 文 件 这 里 先 要 介 绍 W inS oc k 中 阻 塞 与 非 阻 塞 的 概 念
在 W ind ow s 环 境 下 一 般 采 用 非 阻 塞 方 式 对 于 客 户 端 S o ck et来 说 如果 把 C lie n t T y pe 特 性 设 为 ctN o n B lo ck in g 表 示 采 用 非 阻 塞 方 式 进 行 连 接 当位 于 另 一 端 的 服 务 器 端 S o ck et试 图 进 行 读 或 写 时 客 户 端 S o ck et就 会 得 到 通知 ( O n R ead 事 件 或 O n W r ite 事 件 )
对 于 服 务 器 端 S o ck et来 说 如 果 把 Se rv e r T y p e 特 性 设 为 s t N o n B lo c k in g 表 示采 用 非 阻 塞 方 式 进 行 连 接 当 位 于 另 一 端 的 客 户 端 S o ck et 试 图 进 行 读 或 写时 服 务 器 端 S o ck et就 会 得 到 通 知 ( O nC lie n tR e a d 事 件 或 O n C lie n t W rite 事 件 ) 在 响 应 这 些 事 件 的 句 柄 中 都 有 一 个 S o ck et参 数 这 个 参 数 很 有 用 它 就 是 服务 器 端 或 客 户 端 的 S o ck et 对 象 ( T C lie n t W inS oc ke t 或 T S erv e r W in S o ck et 或T S erv e r C lien t W in S o ck et) 这 些 S o ck et对 象 的 共 同 基 类 是 TC u s to m W in S o c k e t T C u s to m W in S o c k e t提 供 了 在 In te rn e t上 传 输 数 据 的 方 法 例 如 要 读 取 数 据可 以 调 用 R ece iv e B u f 或 R ece iv eT ex t 要 发 送 数 据 可 以 调 用 S e ndB uf
S e ndS tre a m S e ndT e x t 或 S e ndS tre a m T h e n D rop 其 中 S e ndS tre a m T h e n D rop
能 够 在 发 送 完 数 据 后 自 动 断 开 S o ck et 的 连 接 S e ndS tre a m 和
S e ndS tre a m T h e n D rop 适 合 于 发 送 流 对 象 例 如 文 件 不 过 您 并 不 需 要 显式 地 删 除 流 对 象 因 为 当 S o ck et之 间 的 连 接 断 开 时 S o ck et会 自 动 释 放 所 有的 流 对 象
与 非 阻 塞 方 式 不 同 的 是 在 阻 塞 方 式 下 没 有 诸 如 O n R ead 或 O n W r ite 等 异 步 事 件 S o ck et必 须 主 动 去 读 或 写 数 据 在 读 或 写 操 作 完 成 之 前 应 用程 序 处 于 等 待 状 态 这 样 就 不 可 避 免 地 会 影 响 整 个 应 用 程 序 的 性 能
对 于 客 户 端 S o ck et来 说 如 果 把 C lie n t T y p e 特 性 设 为 c t B loc k ing 表 示 采 用 阻塞 方 式 进 行 连 接 为 了 尽 可 能 地 减 少 阻 塞 方 式 的 副 作 用 您 可 以 把 所有 涉 及 到 读 写 的 操 作 放 在 一 个 单 独 的 线 程 中 这 样 在 32 位 的 W ind ow s 环 境下 其 它 线 程 能 够 继 续 得 到 执 行 当 然 如 果 在 读 写 函 数 中 客 户 程 序 本 身 没有 其 它 事 情 要 做 您 就 不 必 创 建 一 个 线 程 了
对 于 服 务 器 端 S o ck et来 说 如 果 把 Se rv e r T y p e 特 性 设 为 s t T h re a d B loc k ing 表示 采 用 阻 塞 方 式 进 行 连 接 C+ + Bu ild e r 3 为 每 一 个 阻 塞 方 式 的 连 接 自 动 分 配一 个 新 的 线 程 这 样 即 使 有 某 个 客 户 正 在 进 行 读 写 操 作 其 它 客 户 也 不必 等 待 服 务 器 端 的 S o ck et 用 TS e rv e r C lie n t Th re a d 对 象 来 操 纵 每 一 个 线 程当 线 程 开 始 执 行 时 它 就 检 查 位 于 另 一 端 的 客 户 是 否 正 在 试 图 进 行 写 如是 就 触 发 O n C lie n t R e a d 事 件 如 果 检 查 出 客 户 不 在 试 图 写 它 就 触 发O n C lie n t W rite 事 件 让 服 务 器 去 写
实 际 上 这 种 用 线 程 对 象 来 管 理 连 接 的 方 式 可 以 认 为 是 假 阻 塞 方 式就 编 程 而 言 与 非 阻 塞 方 式 是 相 似 的 比 较 麻 烦 的 是 客 户 端 它 怎 么知 道 对 方 ( 指 服 务 器 端 ) 已 准 备 好 读 或 写 呢 这 就 要 用 到 T W in S o ck etS tre a m 对象 调 用 这 个 对 象 的 W a i t F o r D a ta 可 以 保 证 服 务 器 和 客 户 的 同 步 用
T W in So c k e t S tre a m 对 象 进 行 读 或 写 时 如 果 在 20 秒 内 操 作 还 没 有 完 成
T W in So c k e t S tre a m 对 象 就 认 为 超 时 了 它 就 会 自 动 断 开 连 接 这 样 就 能 避免 应 用 程 序 锁 死 正 是 由 于 T W in S o ck etS tre a m 对 象 具 有 超 时 保 护 机 制 您也 可 以 把 T W in S o ck etS tre a m 对 象 用 于 服 务 器 端 进 行 读 或 写 要 注 意 的 是
T W in So c k e t S tre a m 对 象 不 能 用 于 非 阻 塞 方 式
也 许 有 的 读 者 要 问 既 然 阻 塞 方 式 可 能 会 影 响 应 用 程 序 的 性 能 虽 然 用 多线 程 技 术 可 以 加 以 弥 补 但 又 使 编 程 变 得 复 杂 为 什 么 还 要 用 阻 塞 方式 呢 这 是 因 为 在 阻 塞 方 式 下 读 或 写 是 主 动 的 您 可 以 在 读 或 写 操 作完 成 后 安 全 地 关 闭 S o ck et的 连 接 而 在 非 阻 塞 方 式 下 读 或 写 是 随 机 的S o ck et必 须 经 常 保 持 在 连 接 状 态 才 能 捕 捉 到 异 步 事 件
TC us tom Wi nS oc ket
T C u s to m W in S o c k e t是 S o ck et对 象 的 基 类 它 是 在 SC K T C O M P 单 元 中 声 明 的编 写 W inS oc k 应 用 程 序 有 时 需 要 直 接 操 纵 S o ck et 对 象 因 此 这 里 先 介 绍T C u s to m W in S o c k e t
A ddr 特 性
声 明 _prope r ty s o c k a ddr_ in A d d r ;
这 个 只 读 的 特 性 返 回 本 地 S o ck et的 In te rn e t地 址 其 中 s o c k a ddr_ in 是 一 个 结构
A S y n c S ty le s 特 性
声 明 _prope r ty T A s y nc S ty le s A S y n c S ty le s ;
这 个 特 性 用 于 设 置 S o ck et 可 以 接 收 到 哪 些 异 步 事 件 其 中 TA s y n c S ty le s 是一 个 集 合 可 以 包 含 下 列 元 素 as R e a d ( 当 连 接 已 准 备 好 读 时 ) as W r i te( 当连 接 已 准 备 好 写 时 ) as O O B ( 当 超 出 带 宽 的 数 据 抵 达 时 ) as A cce p t( 当 另 一个 So c k e t 请 求 连 接 时 ) a s C onne c t( 当 与 另 一 个 S o ck et 建 立 了 连 接 时 )
as C lo s e( 当 与 另 一 个 S o ck et 的 连 接 终 止 时 ) 注 意 如 果 S o ck et 设 为 非 阻 塞 ( N on- B loc k ing) 方 式 AS y n c S ty le s 特 性 应 至 少 包 含 as R e a d 和 a s W rite 这 两 个 元素
C o n n ecte d 特 性
声 明 _prope r ty bool C onne c te d ;
这 个 只 读 的 特 性 返 回 S o ck et 是 否 处 于 连 接 状 态 返 回 T ru e 表 示 处 于 连 接 状态 注 意 在 使 用 S o ck et 传 输 数 据 之 前 首 先 要 访 问 C onne c te d 特 性 看 看当 前 是 否 处 于 连 接 状 态
D a ta 特 性
声 明 _prope r ty vo id * D a ta ;
这 个 特 性 是 个 无 类 型 指 针 指 向 一 个 应 用 程 序 专 用 的 数 据 结 构 这 个 数 据结 构 中 可 能 包 含 了 有 关 客 户 端 的 信 息 服 务 器 端 用 此 信 息 判 断 客 户 端 的 连接 请 求
H a nd le 特 性
声 明 _prope r ty H W N D H a nd le ;
这 个 特 性 很 重 要 S o ck et能 接 收 的 异 步 事 件 都 是 以 W ind ow s 消 息 的 形 式 发 给此 句 柄 的
L o c a l A dd re s s 特 性
声 明 _prope r ty S y s te m : : A n s i S tr ing L o c a l A ddre s s ;
这 个 只 读 的 特 性 返 回 一 个 用 点 分 法 表 示 的 本 地 S o ck et 的 IP 地 址 如
123 .197 .1 .2 等 一 个 机 器 可 以 有 多 个 IP 地 址 每 个 IP 地 址 可 以 同 时 用 于多 个 S o ck et 连 接 但 每 一 个 S o ck et 连 接 的 端 口 号 (L o c a l P o r t) 必 须 是 相 异 的 以 区 别 于 同 一 个 IP 地 址 的 其 它 连 接
Lo c a l H o s t 特 性
声 明 _prope r ty S y s te m : : A n s i S tr ing L o c a l H os t;
这 个 只 读 的 特 性 返 回 一 个 用 字 符 方 式 表 示 的 本 地 S o ck et 的 IP 地 址 如
h ttp ://w w w . M y S ite .C o m 等
Lo c a l P o r t 特 性
声 明 _prope r ty in t L o c a l P o r t;
这 个 只 读 的 特 性 返 回 本 地 S o ck et的 端 口 号 对 于 同 一 个 IP 地 址 来 说 可 以 同时 用 于 多 个 S o ck et 连 接 但 每 个 连 接 的 端 口 号 必 须 是 相 异 的 也 就 是 说
L o ca l A d d res s 特 性 和 Lo c a l P o r t特 性 的 组 合 总 是 唯 一 的
R e m o te A dd r 特 性
声 明 _prope r ty s o c k a ddr_ in R e m o te A ddr;
这 个 只 读 的 特 性 返 回 本 地 S o ck et 所 连 接 的 另 一 端 S o ck et 的 In te rn e t 地 址 其中 s o c k a ddr_ in 是 一 个 结 构 R e m o te A ddr 特 性 实 际 上 是 R e m o te A ddre s s 和R e m o te P o r t的 组 合
R e m o te A dd re s s 特 性
声 明 _prope r ty S y s te m : : A n s i S tr ing R e m o te A ddre s s ;
这 个 只 读 的 特 性 以 点 分 法 的 形 式 表 示 另 一 端 S o ck et 的 IP 地 址 如
123 .197 .1 .2
R e m o te H o s t 特 性
声 明 _prope r ty S y s te m : : A n s i S tr ing R e m o te H o s t;
这 个 只 读 的 特 性 返 回 另 一 端 S o ck et的 主 机 名 如 h ttp : // www .wS ite .C o m
R e m o te P o r t 特 性
声 明 _prope r ty in t R e m o te P o r t;
这 个 只 读 的 特 性 返 回 另 一 端 S o ck et所 使 用 的 端 口 号 注 意 如 果 客 户 向 服 务器 请 求 某 种 特 殊 的 服 务 R e m o te P o r t特 性 返 回 的 端 口 号 可 能 不 同 于 客 户 请 求的 端 口 号
S o ck et H a n d le 特 性
声 明 _prope r ty in t S o c k e t H a nd le ;
这 个 只 读 的 特 性 返 回 S o ck et对 象 的 W ind ow s 句 柄 在 直 接 调 用 W inS oc k 的 AP I 时 需 要 用 到 这 个 句 柄 如 果 C onne c te d 特 性 返 回 Fa ls e 也 就 是 说 连 接 还 没 有建 立 S o ck et H a n d le 特 性 就 返 回 INVAL ID _ S OC KE T
C lo s e 函 数
声 明 vo id _fa s tc a ll C los e ( vo id ) ;
这 个 函 数 用 于 断 开 S o ck et连 接 ( 如 果 S o ck et 之 间 已 建 立 了 连 接 的 话 ) 对 于 服务 器 端 S o ck et来 说 调 用 C lo s e 函 数 将 断 开 与 所 有 客 户 的 连 接 并 退 出 监 听 状态 对 于 客 户 端 S o ck et来 说 将 只 断 开 自 己 与 服 务 器 的 连 接 不 会 影 响 到 其它 客 户 的 连 接
L is te n 函 数
声 明 vo id _ fa s tc a ll L is te n ( c ons t S y s te m : : A n s i S tr ing N a m e , c ons t S y s te m : : A n s i S tr ing A ddre s s , c ons t S y s te m : : A n s i S tr ing S e rv ic e , W o rd P o r t, in t Q u eu eS iz e);
这 个 函 数 一 般 由 服 务 器 端 S o ck et 调 用 使 服 务 器 端 S o ck et 进 入 监 听 状 态
N a m e A ddre s s Se rv ic e Po r t 参 数 分 别 取 自 H o s t A ddre s s Se rv ic e Po r t
特 性
Lo c k 函 数
声 明 vo id _fa s tc a ll L o c k ( vo id);
这 个 函 数 将 阻 塞 其 它 正 在 执 行 的 线 程 直 到 调 用 了 U n lo c k 为 止 注 意 一般 情 况 下 不 要 调 用 Lo c k 因 为 这 会 影 响 应 用 程 序 的 性 能
Un lo c k 函 数
声 明 vo id _fa s tc a ll U n lo c k ( vo id);
这 个 函 数 与 Lo c k 函 数 正 相 反 用 于 解 除 对 其 它 线 程 的 阻 塞
L o o kup N a m e 函 数
声 明 in_a d d r _fa s tc a ll L ookupN a m e ( c ons t S y s te m :: A n s i S tr ing n a m e ) ;
这 个 函 数 根 据 N a m e 参 数 指 定 的 主 机 名 返 回 S o ck et相 应 的 In te rn e t地 址 其 中
in_a d d r是 一 个 紧 凑 的 结 构
L o o kupSe r v ic e 函 数
声 明 in t _fa s tc a ll L ooku pS e rv ic e ( c ons t S y s te m : : A n s i S tr in g s e rv ic e ) ;
如 果 服 务 器 提 供 的 是 标 准 的 服 务 如 FT P H TTP F INGE R 每 一 个 标 准 的服 务 都 对 应 着 一 个 事 先 约 定 的 端 口 号 例 如 FT P 服 务 对 应 的 端 口 号 就 是 21 TEL N E T 服 务 对 应 的 端 口 号 就 是 23 NNT P 服 务 对 应 的 端 口 号 就 是 119 这样 只 要 指 定 了 服 务 类 型 端 口 号 就 隐 含 确 定 了 这 个 函 数 根 据 Se rv ic e 参数 指 定 的 服 务 类 型 返 回 相 应 的 端 口 号 关 于 W ind ow s 提 供 的 服 务 及 其 端 口 号的 详 细 描 述 请 参 见 W IN DOW S 目 录 中 的 SE R V IC E S 文 件
R ece iv e B u f 函 数
声 明 in t _fa s tc a ll R e c e iv e B u f ( vo id *B uf, in t C oun t) ;
这 个 函 数 用 于 从 S o ck et连 接 中 读 取 C oun t个 字 节 到 Bu f参 数 中 并 返 回 实 际 读取 的 字 节 数 这 个 函 数 一 般 是 在 处 理 S o ck et 对 象 的 O n S o ck et E v en t 事 件 或 者T S e rve r S oc ke t元 件 的 O n C lie n t R e a d 事 件 或 者 TC l ie n t S o c k e t元 件 的 O n R ead 事 件时 调 用 的
R ece iv e B u f 函 数 只 适 用 于 非 阻 塞 方 式 的 S o ck et 对 于 阻 塞 方 式 的 S o ck et 只能 用 T W in So c k e t S tre a m 来 读 写 信 息 T W in So c k e t S tre a m 只 在 对 方 准 备 好 的 情况 下 才 传 输 数 据
R ece iv e L en g th 函 数
声 明 in t _fa s tc a ll R e c e iv e L e ng th ( vo id);
这 个 函 数 用 于 估 计 从 S o ck et连 接 中 读 取 数 据 要 开 辟 多 大 的 缓 冲 区 ( 字 节 数 )
R ece iv eTe x t 函 数
声 明 S y s te m : : A n s i S tr in g _ fa s tc a l l R e c e iv e T e x t( ) ;
这 个 函 数 从 S o ck et连 接 中 读 取 一 个 字 符 串 并 返 回 这 个 字 符 串 这 个 函 数 一 般在 响 应 S o ck et 对 象 的 O n S o ck et E v en t 事 件 时 调 用 或 者 在 响 应 T S e rve r S oc k e t 元 件 的 O n C lie n t R e a d 事 件 时 调 用 注 意 R ece iv eT ex t函 数 只 适 用 于 非 阻 塞 方式 的 S o ck et对 象
Se ndB u f 函 数
声 明 in t _fa s tc a ll S e ndB uf( v o id *B u f , in t C oun t) ;
这 个 函 数 用 于 把 缓 冲 区 Bu f中 C oun t个 字 节 发 送 到 S o ck et连 接 上 并 返 回 实 际发 送 的 字 节 数 这 个 函 数 一 般 是 在 响 应 S o ck et 对 象 的 O n S o ck et E v en t 事 件 时调 用 或 者 在 响 应 T S e rve r S oc ke t元 件 的 O n C lie n t W rite 事 件 或 T C lie n t S e rv e r 元件 的 O n W r ite 事 件 时 调 用 如 果 在 发 送 数 据 的 函 数 中 出 现 错 误 连 接 将 终 止并 触 发 E S oc ke t E r ro r异 常
Se ndS tre a m 函 数
声 明 bool _fa s tc a ll S e ndS tre a m ( C la s s e s :: T S tre a m * A S tre a m ) ;
这 个 函 数 把 A S tream 参 数 指 定 的 流 发 送 到 S o ck et连 接 中 如 果 发 送 成 功 函数 就 返 回 T ru e 这 个 函 数 一 般 在 响 应 S o ck et 对 象 的 O n S o ck et E v en t 事 件 时 调用 或 者 在 响 应 T S e rve r S oc ke t元 件 的 O n C lie n t W rite 事 件 或 T C lie n t S o c k e t元 件的 O n W r ite 事 件 时 调 用
Se ndS tre a m T h e n D ro p 函 数
声 明 bool _fa s tc a ll S e ndS tre a m T h e n D rop ( C la s s e s : : T S tre a m * A S tre a m ) ;
这 个 函 数 与 S e ndS tre a m 函 数 相 似 也 是 把 AS tre a m 参 数 指 定 的 流 发 送 到 S o ck et 连 接 中 如 果 发 送 成 功 函 数 就 返 回 T ru e 不 同 的 是 发 送 完 毕 后 它 会 自动 终 止 连 接
Se nd Te x t 函 数
声 明 v o id _ fa s tc a ll S e n d T e x t( c o n s t S y s te m ::A n s iS trin g S ) ;
这 个 函 数 用 于 发 送 一 个 字 符 串 这 个 函 数 一 般 在 响 应 S o ck et 对 象 的O n S o ck et E v en t 事 件 时 调 用 或 者 在 响 应 T S e rve r S oc ke t 元 件 的 O n C lie n t W rite 事 件 或 T C lie n t S oc ke t元 件 的 O n W r ite 事 件 时 调 用 如 果 在 发 送 数 据 时 发 生 错误 连 接 将 终 止 并 触 发 E S oc ke t E r ro r异 常
O n S o ck et E v en t 事 件
声 明 _prope r ty T S oc ke t E ve n t E v e n t O n S o c k e t E v e n t;
其 中 T S oc ke t E v e n tE v e n t是 这 样 声 明 的
ty p e d e f vo id _fa s tc a l l (_ c los ure * T S oc ke t E ve n t E v e n t) ( S y s te m :: T O b je c t* S e nd e r , T C u s to m W in S o ck et S o ck et T S oc ke t E ve n t S o c k e t E v e n t) ;
当 S o ck et对 象 接 收 到 一 个 异 步 事 件 的 通 知 就 触 发 这 个 事 件 其 中 S e nde r 参数 和 S o ck et参 数 似 乎 是 重 复 的 都 是 指 接 收 此 事 件 的 S o ck et对 象 S o ck et E v e n t
参 数 是 C+ + 的 枚 举 类 型 |
用 于 表 示 |
事 件 的 种 类 |
可 以 是 以 |
下 值 之 一 |
---|---|---|---|---|
s e L ookup s e C onn e c tin g |
s e C onne c t |
se D isc o n n e c t |
se L iste n |
se A c c e p t |
se W r i te se R e a d |
O n E r ro r E v e n t 事 件
声 明 _prope r ty T S oc ke t E r ro r E ve n t O n E r ro r E ve n t;
其 中 T S oc ke t E r ro r E ve n t是 这 样 声 明 的
ty p e d e f vo id _ fas tcall (_ clo s u re * T S o c ket E r ro r E ven t) ( S y ste m : : T O b ject* S e n d e r , T C u s to m W in S o cket
S o ck et T E r ro r E v e n t E rro rE v e n t in t & E r ror C ode ) ;
当 S o ck et在 创 建 使 用 或 关 闭 连 接 时 发 生 错 误 就 触 发 这 个 事 件 一 般 情 况 下S e nde r 参 数 与 S o ck et 参 数 的 含 义 是 一 致 的 E rro rE v e n t 参 数 用 于 表 明 错 误 的类 型 可 以 是 以 下 值 之 一 eeG e n eral eeS en d ee R ece iv e e e C onne c t
eeD is c o n n ect eeA c cep t
在 处 理 这 个 事 件 的 句 柄 中 如 果 成 功 地 解 决 了 错 误 您 就 把 E rro r C o d e 参 数设 为 0 这 样 能 避 免 触 发 E S oc ke t E r ro r异 常
TC li ent Wi nS oc ket
由 于 S o ck et分 客 户 端 和 服 务 器 端 两 种 因 此 一 个 实 际 的 S o ck et对 象 并 不 是直 接 从 T C u s to m W in S o c k e t 继 承 下 来 的 而 是 从 T C lie n t W inS oc k e t 或T S erv e r W in S o ck e t 或 T S e rve r C lie n t W inS oc k e t 继 承 下 来 的 其 中
T C lien t W in S o ck et 代 表 客 户 端 的 S o ck et 对 象 T S erv e r W in S o ck et 代 表 处 于 监听 状 态 的 服 务 器 端 的 S o ck et对 象 T S e rve r C lie n t W inS oc ke t代 表 已 连 接 的 服 务器 端 的 S o ck et对 象 这 里 先 介 绍 T C lie n tW in S o c k e t
T C lien t W in S o ck et在 Sc k tc o m p 单 元 中 是 这 样 声 明 的
clas s P A S C A L IM P L E M E N T A T IO N T C lien t W in S o ck et : pub l ic S c k tc o m p : : T C u s to m W inS oc k e t
{
ty pe de f S c k tc o m p : : T C u s tom W in S oc ke t in he r i te d; priv a te :
T C lie n t T y p e F C lie n t T y p e ; pro te c te d:
v ir tu a l v o id _ fa s tc a ll C o n n e c t( in t S o c k e t) ;
v o id _ fa s tc a ll S e tC lie n t T y p e ( T C lie n t T y p e V a lu e ) ; pub l ic :
_p rop e r ty T C l ie n t T y pe C l ie n t T y pe ; pub l ic :
_ fa s tc a ll T C lie n t W in S o c k e t( in t A S o c k e t):
S c k tc o m p ::T C u s to m W in S o c k e t( A S o c k e t) { }
_ fa s tc a ll v ir tu a l ~ T C lie n t W in S o c k e t( v o id ) { }
};
可 以 看 出 T C lien t W in S o ck et是 从 TC u s to m W in S o c k e t继 承 下 来 的 增 加 了 一个 C lie n t T y pe 特 性 用 于 区 别 阻 塞 方 式 的 S o ck et和 非 阻 塞 方 式 的 S o ck et
如 果 把 C lie n t T y pe 特 性 设 为 ctN o n B lo ck in g 表 示 客 户 端 S o ck et为 非 阻 塞 方 式可 以 响 应 异 步 的 读 或 写 事 件 ( O n S oc ke t E ve n t) 在 进 行 读 或 写 的 操 作 时 不影 响 其 它 线 程 的 执 行
如 果 把 C lie n t T y pe 特 性 设 为 c t B loc k ing 表 示 客 户 端 S o ck et为 阻 塞 方 式 读 或写 的 操 作 必 须 在 两 端 同 步 进 行 在 阻 塞 方 式 下 您 最 好 把 所 有 涉 及 到 读 或写 的 操 作 放 在 一 个 单 独 的 线 程 中 这 样 在 32 位 的 W ind ow s 环 境 下 能 最 大 限度 地 减 少 对 其 它 线 程 的 影 响 在 C lie n t T y p e 特 性 设 为 c t B loc k ing 的 情 况 下不 会 产 生 异 步 的 读 或 写 事 件 此 时 用 T W in S o ck etS tre a m 对 象 来 进 行 读 写 操作 T W in So c k e t S tre a m 的 超 时 机 制 能 保 证 即 使 在 读 写 操 作 中 出 现 错 误 也 不
会 使 整 个 应 用 程 序 挂 起
TS er ver Wi nS oc ket
T S erv e r W in S o ck e t用 于 描 述 处 于 TC P / IP 监 听 状 态 的 服 务 器 端 S o ck et 一 个 服务 器 端 S o ck et可 以 同 时 连 接 多 个 客 户 端 S o ck et 与 不 同 客 户 的 连 接 都 有 其 单独 的 执 行 线 程
T S erv e r W in S o ck e t在 Sc k tc o m p 单 元 中 是 这 样 声 明 的
clas s P A S C A L IM P L E M E N T A T IO N T S erv e r W in S o ck et :
pub l ic S c k tc o m p : : T C u s to m W inS oc k e t
{
ty pe de f S c k tc o m p : : T C u s tom W in S oc ke t in he r i te d; priv a te :
// 私有的成 员此处省略
pro te c te d:
// 保护的成 员此处省略
pub l ic :
_ fa s tc a ll T S e rv e r W in S o c k e t( in t A S o c k e t);
_fa s tc a l l v ir tua l ~ T S e rv e r W inS oc ke t( vo id);
T S e rv e r C lie n t T h re a d * _ fa s tc a ll G e tC lie n t T h re a d ( T S e rv e r C lie n t W in S o c k e t* C l ie n t S o cket);
_p rop e r ty in t A c t iv e C on ne c t ions ;
_ p ro p e rty in t A c tiv e T h re a d s ;
_p rop e r ty T C us to m W in S o c k e t* C o n n e c t ions [ int In d e x ];
_ p ro p e rty in t Id le T h re a d s ;
_ p ro p e r ty T S erv e r T y p e S e rv er T y p e ;
_ p ro p e r ty in t T h read C a c h eS ize;
_p rop e r ty T G e t S o c k e t E v e n t O n G e t S oc ke t ;
_ p ro p e r ty T G et T h read E v e n t O n G e t T h rea d ;
_ p ro p e rty T T h re a d N o tify E v e n t O n T h re a d S ta rt;
_p rop e r ty T T hre a d N o t ify E v e n t O n T h re a d E n d;
_p rop e r ty T S oc k e t N o tify E ve nt O n C l ie n t C o n n e c t ;
_p rop e r ty T S oc k e t N o tify E ve nt O n C l ie n t D isc o n n e c t ;
_p rop e r ty T S oc k e t N o tify E ve nt O n C l ie n t R e a d ;
_p rop e r ty T S oc k e t N o tify E ve nt O n C l ie n t W r ite ;
_p rop e r ty T S oc k e t E r ro r E v e n t O n C l ie n t E r ro r ;
};
可 以 看 出 T S erv e r W in S o ck et也 是 从 TC u s to m W in S o c k e t继 承 下 来 的 不 过 它增 加 了 一 些 特 性 方 法 和 事 件 这 是 因 为 处 于 监 听 状 态 的 服 务 器 端 S o ck et需要 管 理 多 个 连 接
S erv e r Ty p e 特 性
声 明 _prope r ty T S e rve r T y p e S e rv e r T y pe ;
这 个 特 性 用 于 设 置 与 客 户 的 连 接 方 式 如 果 设 为 s t T h re a d B loc k ing 表 示 与
每 一 个 客 户 的 连 接 都 自 动 分 配 一 个 线 程 (T S e rv e r C lie n t T h re a d 对 象 ) 当 服 务器 端 S o ck et需 要 读 或 写 时 就 触 发 O n C lie n t R e a d 事 件 或 O n C lie n t W rite 事 件
如 果 设 为 s t N o n B lo c k in g 表 示 用 非 阻 塞 方 式 连 接 每 一 个 客 户 每 个 连 接 都在 一 个 单 独 的 线 程 中 处 理 并 且 用 O n C lie n t R e a d 或 O n C lie n t W r i te 来 通 知 服 务器 端 S o ck et进 行 读 或 写
A c tiv e C o n n e c tio n s 特 性
声 明 _prope r ty in t A c tive C onn e c t ions ;
这 个 只 读 的 特 性 返 回 当 前 活 动 的 连 接 数 实 际 上 也 就 是 C onne c tions 数 组 的元 素 个 数
A c tive T h re ad s 特 性
声 明 _prope r ty in t A c tive T h re a d s ;
这 个 只 读 的 特 性 返 回 当 前 正 在 使 用 的 T S e rve r C lie n tT h re a d 对 象 的 个 数 服 务器 端 的 S o ck et对 象 用 TS e rv e r C lie n t Th re a d 来 管 理 与 客 户 连 接 的 每 个 线 程
C o nne c tio n s 特 性
声 明 _prope r ty T C u s to m W in S o c k e t* C onne c tions [ int Inde x]
这 个 特 性 是 一 个 数 组 数 组 的 每 一 个 元 素 都 代 表 一 个 当 前 活 动 的 连 接 ( T S e rv e r C lie n tW inS oc ke t对 象 ) 索 引 为 0 的 元 素 代 表 第 一 个 连 接 索 引 为 1 的元 素 代 表 第 二 个 连 接 依 次 类 推 该 数 组 的 元 素 个 数 就 是 A c tiv e C onne c t ions 特 性 的 值
如 果 Se rv e r T y p e 特 性 设 为 s t T h re a d B loc k ing 与 每 一 个 连 接 ( T S e rv e r C lie n tW inS oc ke t 对 象 ) 所 对 应 的 线 程 (T S e rv e r C lie n t T h r e a d 对 象 ) 可 以通 过 G e tC l ie n tT h re a d 函 数 返 回
T h re a d C a ch eS iz e 特 性
声 明 _ p ro p e r ty in t T h re ad C a ch eS iz e;
如 果 Se rv e r T y p e 特 性 设 为 s t T h re a d B loc k ing 每 一 个 与 客 户 的 连 接 都 将 自 动 分配 一 个 线 程 为 了 改 善 应 用 程 序 的 性 能 即 使 连 接 已 断 开 C+ + Bu ild e r 3 并不 删 除 对 应 的 线 程 (T S e rv e r C lie n t T h re a d 对 象 ) 而 是 把 它 保 存 在 缓 存 中 这样 当 建 立 新 的 连 接 时 就 可 以 重 用 在 缓 存 中 的 线 程 对 象 而 不 需 要 新 建 一个 线 程 对 象
那 么 在 缓 存 中 保 存 多 少 个 线 程 对 象 呢 这 是 由 T h re a d C ach eS iz e 特 性 指 定的 T h re a d C ach eS iz e 特 性 的 值 并 非 越 大 越 好 如 果 缓 存 的 线 程 对 象 太 多实 际 又 用 不 了 这 么 多 将 造 成 资 源 的 浪 费 但 如 果 T h re a d C ach eS iz e 特 性 的值 设 得 过 小 又 将 影 响 应 用 程 序 的 性 能
I d le T h re a d s 特 性
声 明 _prope r ty in t Id le T h re a d s ;
这 个 只 读 的 特 性 返 回 没 有 派 上 用 场 ( 空 闲 ) 的 线 程 对 象 的 个 数 如 果Id le T h re a d s 特 性 返 回 的 值 过 大 说 明 T h re a d C a ch eS iz e 特 性 设 得 过 大 这 时 候您 可 以 参 照 A c tiv eT h read s 特 性 的 值 重 新 调 整 T h re a d C a ch eS iz e 特 性 的 值
G e t C lie n t T h re a d 函 数
声 明 T S erv er C lien tT h read * _ fastc all G e tC lien tT h read ( T S erv erC lien tW in S o ck e t* C lien tS o ck et);
这 个 函 数 返 回 由 C lie n t S o ck et参 数 指 定 的 连 接 所 对 应 的 线 程 对 象
O n C lie n t C o n n e c t 事 件
声 明 _prope r ty T S oc ke t N o tif y E ve n t O n C lie n t C onne c t;
其 中 T S oc ke t N o tify E ve n t是 这 样 声 明 的
ty p e d e f v o id _ fa s tc a ll (_ c lo su re * T S o c k e t N o tify E v e n t) ( S y s te m ::T O b je c t* S e n d e r, T C u s to m W in S o c k e t* S o c k e t) ;
当 服 务 器 端 S o ck et 进 入 监 听 状 态 时 将 触 发 O n S o ck et E v en t 事 件 So c k e t E v e n t
参 数 设 为 se L iste n 当 处 于 监 听 状 态 的 服 务 器 端 S o ck et 监 听 到 客 户 的 连 接 请求 就 自 动 接 收 客 户 的 请 求 并 触 发 O n G e t S o c k e t 事 件 这 时 候 又 将 触 发O n S o ck et E v en t事 件 S o ck et E v en t参 数 设 为 s e A cce p t 如 果 Se rv e r T y p e 特 性 设为 s t T h re a d B lo c k ing 而 缓 存 中 又 没 有 线 程 对 象 可 以 重 用 将 触 发 O n G e t T h re a d 事 件 在 处 理 O n G e t T h re a d 事 件 的 句 柄 中 如 果 没 有 显 式 地 创 建 一 个 线 程 对象 服 务 器 端 的 S o ck et对 象 将 自 动 创 建 一 个 线 程 对 象 (T S e rv e r C lie n t T h re a d ) 创 建 了 线 程 对 象 后 线 程 开 始 执 行 时 又 将 触 发 O n T h re a d S ta r t 事 件 最 后 将触 发 O n C lie n tC onne c t事 件 通 知 服 务 器 端 So c k e t连 接 已 完 成
注 意 在 这 里 S e nde r 参 数 和 S o ck et参 数 的 含 义 是 不 同 的 S e nde r 参 数 是 处 于监 听 状 态 的 服 务 器 端 S o ck et 对 象 (T S e rv e r W in C l ie n t) 而 So c k e t 参 数 是T S erv e r C lien t W in S o ck et对 象
O n C lie n t D is c o nne c t 事 件
声 明 _prope r ty T S oc ke t N o tif y E ve n t O n C lie n t D is c onne c t;
当 服 务 器 端 S o ck et与 某 个 客 户 的 连 接 被 断 开 时 将 触 发 这 个 事 件 同 时 相 应的 T S erv e r C lien t W in S o ck et 对 象 被 删 除 如 果 Se rv e r T y p e 特 性 设 为 s t T h re a d B lo c k ing 在 触 发 了 O n C lie n tD is c onne c t 事 件 之 后 还 将 触 发O n Th re a d En d 事 件
O n C lie n t E r ro r 事 件
声 明 _prope r ty T S oc ke t E r ro r E ve n t O n C lie n t E r ro r ;
其 中 T S oc ke t E r ro r E ve n t是 这 样 声 明 的
ty p e d e f v o id _ fa s tc a ll (_ c lo su re * T S o c k e tE r ro r E v e n t)( S y s te m ::T O b je c t* S e n d e r , T C u s to m W in S o ck et S o c k et T E rro r E v e n t E r ro rE v e n t in t & E r ro r C o d e ) ;
当 服 务 器 端 S o ck et对 象 在 建 立 使 用 和 终 止 与 某 客 户 的 连 接 时 出 现 错 误 将 触
发 这 个 事 件 如 果 在 处 理 此 事 件 的 句 柄 中 解 决 了 错 误 您 可 以 把 E rro r C o d e 参 数 设 为 0 这 样 就 能 避 免 触 发 E S oc ke t E r ro r 异 常 E rro rE v e n t参 数 是 错 误 的类 型 可 以 是 以 下 值 之 一 eeG e n eral eeS en d ee R ece iv e e e C onne c t
eeD is c o n n ect eeA c cep t
O n C lie n t R e a d 事 件
声 明 _prope r ty T S oc ke t N o tif y E ve n t O n C lie n t R e a d ;
C+ + Bu ild e r 3 用 这 个 事 件 通 知 服 务 器 端 S o ck et对 象 去 读 取 有 关 信 息
O n C lie n t W r ite 事 件
声 明 _prope r ty T S oc ke t N o tif y E ve n t O n C lie n t W r i te ;
C+ + Bu ild e r 3 用 这 个 事 件 通 知 服 务 器 端 S o ck et对 象 去 写 信 息
O n G e t S o c k e t 事 件
声 明 _prope r ty T G e t S o c k e t E v e n t O n G e t S oc k e t;
其 中 T G et S o c k et E v en t是 这 样 声 明 的
ty pe de f v o id _ fa s tc a l l (_ c losure * T G e t S oc ke t E ve n t) ( S y s te m : : T O b je c t* S e nd e r, in t S o ck et, Ts erv e r C l ie n t- W in S o c k e t* & C l ie n t S o ck et);
C+ + Bu i ld e r 3 用 这 个 事 件 通 知 服 务 器 端 S o ck et 需 要 创 建 一 个 新 的
T s erv e r C lien t- W in S o c - k et 对 象 来 管 理 与 客 户 的 连 接 创 建 的
T S erv e r C lien t W in S o ck et对 象 由 C lie n t S o c k e t参 数 返 回
O n G e t T h re a d 事 件
声 明 _prope r ty T G e t T h re a d E v e n t O n G e t T hre a d;
其 中 T G et T h read E v en t是 这 样 声 明 的
ty pe de f v o id _ fa s tc a l l (_ c losure * T G e t T hre a dE ve n t) ( S y s te m : : T O b je c t* S e n d e r, T S e rv e r C l ie n t W inS oc ke t* C l ie n t S o c k e t , T S e rv e r C l ie n t T h re a d* & S oc k e t T hre a d ) ;
C+ + Bu i ld e r 3 用 这 个 事 件 通 知 服 务 器 端 S o ck et 需 要 创 建 一 个 新 的
T S erv e r C lien t T h re a d 对 象 新 创 建 的 TS e rv e r C lie n t Th re a d 对 象 由 S o ck etT h read
参 数 返 回
O n Th re a d En d 事 件
声 明 _prope r ty T T hre a d N o tif y E v e nt O n T h re a d E nd;
如 果 Se rv e r T y p e 特 性 设 为 s t T h re a d B loc k ing 当 服 务 器 端 S o ck et与 某 个 客 户 的连 接 断 开 时 将 触 发 O n Th re a d En d 事 件 在 此 事 件 触 发 之 前 已 触 发 了O n C lie n tD is c onne c t事 件
O n T h re a dS ta r t 事 件
声 明 _prope r ty T T hre a d N o tif y E v e nt O n T h re a d S ta r t;
如 果 Se rv e r T y p e 特 性 设 为 s t T h re a d B loc k ing 当 服 务 器 端 S o ck et建 立 了 一 个 新的 连 接 新 的 线 程 开 始 执 行 时 就 会 触 发 这 个 事 件
7 . 8 TS er ver Cl ie nt Win So ck et
T S erv e r C lien t W in S o ck et用 于 描 述 与 某 个 客 户 连 接 的 服 务 器 端 S o ck et对 象 有的 读 者 也 许 要 问 T S erv e r W in S o ck et也 是 用 于 描 述 服 务 器 端 的 S o ck et 那 么它 们 两 者 之 间 的 区 别 在 哪 里 呢 当 您 把 T S e rve r S oc ke t 元 件 放 到 Fo rm 或 数 据模 块 上 并 进 入 监 听 状 态 就 自 动 创 建 了 服 务 器 端 的 S o ck et 对 象 ( T S e rv e r W inS oc ke t) 只 有 当 服 务 器 端 S o ck et 监 听 到 一 个 客 户 的 连 接 请 求 并接 收 了 连 接 请 求 后 才 创 建 一 个 相 应 的 T S e rve r C lie n tW inS oc ke t 对 象 当 与
该 客 户 的 连 接 断 开 时 相 应 的 T S e rve r C lie n tW inS oc ke t对 象 将 被 删 除在 Sc k tc o m p 单 元 中 T S erv e r C lien t W in S o ck et是 这 样 声 明 的
c la s s P A S C A L IM P L E M E N T A T IO N T S e rve r C l ie n t W inS oc ke t : pub l ic S c k tc o m p : : T C u s to m W inS oc k e t
{
ty pe de f S c k tc o m p : : T C u s tom W in S oc ke t in he r i te d; priv a te :
T S erv e r W in S o ck e t* F S e rv er W in S o c ket; pub l ic :
_fa s tc a l l T S e rve r C l ie n t W inS oc k e t( in t S o c k e t , T S e rve r W in S o c k e t* S e rv e r W inS oc k e t) ;
_ fa s tc a ll v ir tu a l ~ T S e rv e r C lie n t W in S o c k e t(v o id ) ;
_p rop e r ty T S e rv e r W in S o c k e t* S e rv e r W in S oc ke t ;
};
可 以 看 出 T S e rve r C lie n tW inS oc ke t 也 是 从 T C u s to m W in S o c k e t 继 承 下 来 的增 加 了 一 个 S e rv e r W inS oc ke t特 性 并 且 重 载 了 构 造 函 数 和 析 构 函 数
S erv e r W in S o ck e t 特 性
声 明 _prope r ty T S e rve r W in S o c k e t* S e rv e r W inS oc ke t;
这 个 只 读 的 特 性 返 回 处 于 监 听 状 态 的 服 务 器 端 S o ck et 对 象
( T S e rv e r W inS oc ke t)
7.9 TW in Soc ke tS tr eam
T W in So c k e t S tre a m 用 于 在 阻 塞 方 式 下 进 行 读 或 写 操 作 也 许 有 的 读 者要 问 S o ck et对 象 本 身 提 供 了 读 写 的 方 法 为 什 么 还 要 用 T W in S o ck etS tr e a m 呢 这 是 因 为 T w in S o c k e t- S tre a m 还 提 供 了 同 步 和 超 时 保 护 机 制
在 Sc k tc o m p 单 元 中 T W in So c k e t S tre a m 是 这 样 声 明 的
clas s P A S C A L IM P L E M E N T A T IO N T W in S o ck et S tream : p u b l ic C lass e s : : T S tre a m
{
ty p e d e f C la s se s ::T S tre a m in h e rite d ; priv a te :
T C u s to m W in S o ck et* F S o ck et; in t F T im e o u t ;
pub l ic :
_ fa s tc a ll T W in S o c k e t S tre a m ( T C u s to m W in S o c k e t* A S o c k e t, in t T im e O u t);
_fa s tc a l l v ir tua l ~ T W inS oc ke t S tre a m ( v o id); b o o l _ fa s tc a ll W a itF o r D a ta ( in t T im e o u t) ;
v ir tu a l in t _ fa s tc a ll R e a d ( v o id * B u f fe r , in t C o u n t) ;
v ir tu a l in t _ fa s tc a ll W rite ( c o n s t v o id * B u f fe r , in t C o u n t) ; v ir tu a l in t _ fa s tc a ll S e e k ( in t O f fs e t , W o rd O rig in ) ;
_ p ro p e rty in t T im e O u t;
};
可 以 看 出 T W in S o ck etS tre a m 是 从 T S tream 继 承 下 来 的 并 且 重 载 了 T S tream
的 构 造 函 数 和 析 构 函 数 因 此 T W in S o ck etS tre a m 具 有 流 操 作 的 能 力
T im e O u t 特 性
声 明 _prope r ty in t T im e O u t;
这 个 特 性 用 于 指 定 一 个 毫 秒 数 当 读 或 写 操 作 的 时 间 超 过 这 个 数 就 认 为失 败
构 造 函 数
声 明 _fa s tc a l l T W in S o c k e t S tre a m ( T C u s to m W inS oc k e t* A S oc ke t , in t T im e O u t) ; 在 使 用 T W in So c k e t S tre a m 进 行 读 写 操 作 之 前 首 先 要 用 构 造 函 数 创 建T W in So c k e t S tre a m 的 实 例 A S oc ke t 参 数 用 于 指 定 要 用 T W in S o ck etS tr e a m 进行 读 写 操 作 的 S o ck et对 象 一 般 是 阻 塞 方 式 的 客 户 端 S o ck et对 象 也 可能 是 阻 塞 方 式 的 服 务 器 端 S o ck et对 象 但 不 能 是 非 阻 塞 方 式 的 S o ck et 对 象 否 则 将 触 发 E S oc ke t E r ro r异 常 T im e O u t参 数 用 于 指 定 超 时 的 门 槛 值以 毫 秒 为 单 位 默 认 是 20000 毫 秒 程 序 示 例 如 下
v o id _ fa s tc a ll T M y C lie n t T h re a d ::E x e c u te ( )
{
T W in S o c k e tS tre a m * p S tre am = n e w T W in S o ck et S tream ( C l ie n t S o c k et1 -> S o c ket,6 0 0 0 ) ; tr y
{
w h ile ( ! T e rm in a te d & & C lie n t S o c k e t1 -> A c tiv e )
{
tr y
{
}
ch ar b u f fe r [ 1 0 ];
G e tN e x tR e q u e s t( b u f fe r) ;
p S tre a m -> W r i te ( b u ffe r , s trle n (b u ffe r) + 1 ) ;
...
catch ( E x c e p t io n & E )
{
if ( ! E .C la s s N a m e Is ( " E A b o rt" ))
S y n c h ro n iz e ( H a n d le T h re a d E x c e p tio n ( ) ) ;
}
}
}
_fin a l ly
{
d e le te p S tre a m ;
}
}
注 意 不 要 把 T W in S o ck etS tre a m 与 S o ck et 对 象 的 S e ndS tre a m 和S e ndS tre a m T h e n D rop 混 淆 起 来 后 者 也 是 针 对 流 对 象 进 行 操 作 但 您 并 不需 要 显 式 地 删 除 流 对 象 因 为 当 S o ck et之 间 的 连 接 断 开 时 S o ck et会 自 动 释
放 所 有 的 流 对 象 而 T W in S o ck etS tre a m 对 象 的 实 例 不 会 自 动 删 除 需 要 您显 式 地 调 用 de le te 删 除 它
W a it F o r D a ta 函 数
声 明 bool _fa s tc a ll W a i t F o r D a ta ( in t T im e ou t) ;
这 个 函 数 用 于 等 待 对 方 准 备 好 读 或 写 T im e O u t参 数 指 定 等 待 的 时 间 以 毫秒 为 单 位 如 果 在 规 定 的 时 间 内 对 方 准 备 好 了 这 个 函 数 就 返 回 T ru e 否则 就 返 回 Fa ls e
R e a d 函 数
声 明 v ir tua l in t _fa s tc a l l R e a d ( v o id *B uffe r , in t C o un t) ;
这 个 函 数 类 似 于 S o ck et对 象 的 R ead B u f 用 于 读 取 C ount个 字 节 到 Bu f fe r 指 定的 缓 冲 区 中 并 返 回 实 际 读 到 的 字 节 数 如 果 在 读 的 函 数 中 出 现 错 误 或 连接 的 速 度 很 慢 整 个 应 用 程 序 不 会 一 直 等 待 只 要 读 操 作 占 用 的 时 间 超 过了 事 先 设 定 的 门 槛 值 例 如 20 秒 R ead 函 数 就 放 弃 此 次 读 操 作 并 返 回 0
如 果 读 操 作 确 实 需 要 占 用 较 长 的 时 间 您 要 么 设 置 T im e O u t特 性 把 超 时 的 门槛 值 放 大 要 么 把 较 长 的 操 作 分 成 几 次 较 短 的 操 作 然 后 逐 个 调 用 R ead 函数
注 意 在 调 用 R ead 之 前 一 定 要 先 调 用 W a i t F o r D a ta 以 保 证 对 方 So c k e t 已 准备 好
W r ite 函 数
声 明 v ir tua l in t _fa s tc a l l W r i te ( c ons t vo id *B uffe r , in t C oun t) ;
这 个 函 数 类 似 于 S o ck et 对 象 的 W r ite B u f 用 于 从 Bu f fe r 参 数 指 定 的 缓 冲 区 中发 送 C ount个 字 节 并 返 回 实 际 发 送 的 字 节 数 如 果 在 发 送 的 函 数 中 出 现 错误 或 连 接 的 速 度 很 慢 整 个 应 用 程 序 不 会 一 直 等 待 只 要 写 操 作 占 用 的 时间 超 过 了 事 先 设 定 的 门 槛 值 例 如 20 秒 W r ite 函 数 就 放 弃 此 次 读 操 作 并 返 回0
如 果 要 发 送 的 数 据 确 实 很 长 您 要 么 设 置 T im e O u t 特 性 把 超 时 的 门 槛 值 放大 要 么 把 较 长 的 操 作 分 成 几 次 较 短 的 操 作 然 后 逐 个 调 用 W r ite 函 数
注 意 在 调 用 W r ite 之 前 一 定 要 先 调 用 W a i t F o r D a ta 以 保 证 对 方 S o ck et 已 准备 好
1 0 一 个 网 上 交 谈 (C ha t) 程 序
下 面 我 们 剖 析 一 个 示 范 程 序 这 个 程 序 用 T S e rve r S oc ke t元 件 和 T C lie n t S oc ke t 元 件 写 了 一 个 网 上 交 谈 (C h a t) 程 序 要 说 明 的 是 这 个 程 序 是 用 D e lphi 3 写的 C+ + Bu ild e r 3 的 程 序 员 可 以 从 中 学 到 W inS oc k 编 程 的 基 本 技 巧
Ch a t 程 序 只 有 一 个 Fo rm 这 个 Fo rm 上 同 时 放 了 T S e rve r S oc ke t 元 件 和T C lie n t S oc ke t元 件 表 示 Ch a t程 序 既 是 TC P / IP 服 务 器 也 是 TC P /IP 客 户 为了 分 别 显 示 交 谈 双 方 的 内 容 Ch a t程 序 用 了 两 个 TM e m o 元 件 此 程 序 运 行后 如 图 7 .1 所 示
图 7 .1 一 个 网 上 交 谈 程 序
在 网 上 交 谈 是 一 种 非 标 准 的 服 务 因 此 交 谈 双 方 约 定 端 口 号 (P o r t特 性 ) 为
1024 S o ck et之 间 连 接 类 型 为 非 阻 塞 方 式 ( N onB lo c k ing)
由 于 T S e rve r S oc ke t元 件 的 A c tiv e 特 性 设 为 Fa ls e 因 此 Ch a t程 序 刚 开 始 运 行的 时 候 首 先 要 使 服 务 器 进 入 监 听 状 态 代 码 如 下
P ro ced u re T C h a t F o rm .F o rm C reate( S e n d er: T O b ject); B e g in
F ile L is te n I te m C lic k ( n il) ; En d ;
F ile L is te n I te m C lic k 也是处理 F ile 菜单上的 L is te n 命令的句柄 它是这样定 义的
P ro ced u re T C h a t F o rm .F i le L is ten I tem C l ic k ( S e n d er: T O b ject); B e g in
F i le L is te n I tem . C h eck ed := n o t F i le L is ten I tem .C h e c k e d ; I f F i le L is ten I tem . C h eck e d th e n B e g in
C lie n t S o c k e t .A c tiv e := F a ls e ; S e rv er S o c k et.A ctiv e := T ru e ;
S ta tu s b a r1 .P a n e ls [ 0 ] .T e x t := 'L is te n in g ...'
En d
E ls e B e g in
I f S e rv er S o c k et.A ctiv e th e n S e rv er S o cket. A ctiv e := F a ls e; S tatu s b a r 1 .P an els [ 0 ] .T e x t := '';
En d ; En d ;
F ile L is te n I te m C lic k 实 际 上 是 一 个 切 换 程 序 如 果 服 务 器 已 处 于 监 听 状 态就 退 出 监 听 状 态 如 果 服 务 器 不 在 监 听 状 态 就 让 服 务 器 进 入 监 听 状 态 为 了 直 观 起 见 当 服 务 器 处 于 监 听 状 态 就 在 L is te n 命 令 的 左 边 显 示 一个 符 号 并 且 在 状 态 栏 上 显 示 L is te n in g 如 果 服 务 器 不 在 监 听 状 态 就 取 消 L is te n 命 令 左 边 的 符 号 同 时 让 状 态 栏 显 示 空 白
服 务 器 进 入 监 听 状 态 后 客 户 需 要 提 出 连 接 请 求 待 服 务 器 接 受 了 连 接 请求 后 交 谈 双 方 才 可 以 进 行 交 谈 这 是 通 过 F ile 菜 单 上 的 C onne c t…
命 令 或 按 钮 实 现 的
P ro c e d u re T C h a tF o rm .F ile C o n n e c tIte m C lic k ( S e n d e r : T O b je c t); B e g in
I f C lie n t S o c k e t .A c tiv e th e n C lie n t S o c k e t .A c tiv e := F a ls e ;
I f In p u t Q u e ry ( 'C o m p u ter to c o n n ect to ', 'A d d res s N a m e :', S e rv er) th en If L e n g th ( S e rv e r) > 0 th e n
W ith C lie n t S o c k e t d o B e g in H o s t := S e rv e r ;
A c tiv e := T ru e ;
En d ;
En d ;
F ile C onne c t I te m C lic k 实 际 上 也 是 一 个 切 换 程 序 如 果 客 户 与 服 务 器 已 连 接就 断 开 连 接 接 着 在 一 个 询 问 框 内 键 入 要 连 接 的 服 务 器 的 地 址 ( 指 主 机 名 ) 然 后 建 立 连 接
当 客 户 提 出 连 接 请 求 的 时 候 在 服 务 器 端 和 客 户 端 都 将 触 发 O n C onne c t 事件 在 客 户 端 是 这 样 处 理 O n C onne c t事 件 的
P ro c e d u re T C h a tF o rm .C lie n t S o c k e t C o n n e c t( S e n d e r : T O b je c t; S o c k e t: T C u s to m W in S o c k e t) ; B e g in
S tatu s b a r 1 .P an els [ 0 ] .T e x t := 'C o n n e cted to : '
- S o cket.R em o teH o s t ; En d ;
上 面 这 个 句 柄 实 际 上 就 是 在 状 态 栏 上 显 示 C onne c te d to : 后 跟 服 务 器 的 主机 名
当 服 务 器 监 听 到 客 户 的 连 接 请 求 就 把 M e m o 2 清 空 准 备 开 始 交 谈 代 码
如 下
P roc e d ure T C h a tF orm .S e rv e rS o ck e tC lien tC o n n e c t( S en d e r:T O b jec t;S oc k e t:T C u s tom W inS oc ke t); B e g in
M e m o2 .L ine s . C le a r ; En d ;
当 服 务 器 接 受 了 客 户 的 连 接 请 求 将 触 发 O n A c c e p t事 件
P ro ced u re T C h a t F o rm .S e rv er S o c k et A cce p t( S e n der: T O bje c t ; S o ck et: T C u s to m W in S o ck et); B e g in
Is S e rv e r := T ru e ;
S tatu s b a r 1 .P an els [ 0 ] .T e x t := 'C o n n e cted to : '
- S o cket.R em o teA d d re s s ; En d ;
Is S e rv e r 是 Ch a t程 序 中 一 个 私 有 的 布 尔 类 型 的 变 量 当 服 务 器 接 受 了 一 个 客户 的 连 接 请 求 也 就 是 说 成 为 名 副 其 实 的 服 务 器 后 就 把 这 个 私 有 的 变 量 设为 T ru e
建 立 了 连 接 后 客 户 就 可 以 在 M e m o 1 中 键 入 字 符 开 始 交 谈 按 下 En te r 键除 了 使 文 本 换 行 外 还 把 光 标 所 在 的 行 作 为 文 本 发 出 去 代 码 如 下
P roc e d ure T C h a t F orm .M e m o1K e y D o w n ( S e n de r : T O b je c t ; va r K e y : W o rd ; S h if t : T S h if t S ta te ) ; B e g in
I f K e y = VK _ R e tu rn th e n If Is S e rv e r th e n
S e rv e r S o c k e t .S oc ke t . C o n n e c t io n s [ 0 ] .S e ndT e x t( M e m o1 .L ine s [ M e m o1 .L ine s . C o u n t - 1 ])
En d ;
E ls e
C l ie n t S o c k e t .S o c k e t .S e n d T e x t( M e m o1 .L ine s [ M e m o 1 .L ine s .C o u n t - 1 ]) ;
上 面 这 段 程 序 首 先 判 断 按 下 的 是 否 是 En te r键 如 是 再 判 断 Is S e rv e r是 否 为T ru e 如 是 就 从 T S e rve r S oc ke t元 件 的 S o ck et 特 性 返 回 服 务 器 端 的 S o ck et 对象 再 由 此 对 象 的 C onne c tions 数 组 的 第 一 个 元 素 ( 也 只 有 一 个 元 素 ) 得 到T S erv e r C lien t W in S o ck et 对 象 最 后 调 用 此 对 象 的 S e ndT e x t 把 光 标 所 在 行 的文 本 发 出 去 如 果 Is S e rv e r 为 Fa ls e 就 从 T C lie n t S oc ke t 元 件 的 S o ck et 特 性 得到 客 户 端 S o ck et对 象 再 调 用 S e ndT e x t把 光 标 所 在 行 的 文 本 发 出 去
当 客 户 端 收 到 文 本 后 就 把 收 到 的 文 本 添 加 在 M e m o 2 的 最 后 代 码 如 下
P ro ced u re T C h a t F o rm .C l ie n t S o ck et R e a d ( S en d e r : T O b je c t ; S o ck et: T C u s to m W in S o ck e t) ; B e g in
M e m o2 .L ine s . A d d( S o c k e t .R e c e iv e T e x t) ; En d ;
当 服 务 器 端 收 到 文 本 后 也 把 收 到 的 文 本 添 加 在 M e m o 2 的 最 后 代 码 如 下
P roc e d ure T C h a tF orm .S e rv e rS o ck e tC lien tR e a d (S en d e r:T O b jec t;S o c k e t:T C u stom W inS ocke t); B e g in
M e m o2 .L ine s . A d d( S o c k e t .R e c e iv e T e x t) ; En d ;
此 外 在 客 户 端 还 增 加 了 处 理 错 误 的 代 码
P ro c e d u re T C h a tF o rm . C lie n t S o c k e t E r ro r ( S e n d e r : T O b je c t; S o c k e t: T C u s to m W in S o c k e t ;
E rro rE v e n t : T E r ro rE v e n t ; v a r E rro r C o d e : In te g e r); B e g in
M e m o2 .L ine s . A d d ( 'E r ro r c o n n e c t ing to : ' + S e rv e r ) ; E rro rC o d e := 0 ;
En d ;
至 此 一 个 能 够 在 网 上 交 谈 的 程 序 基 本 写 好 了 最 后 要 说 明 的 是 编 译 此程 序 后 您 可 以 把 执 行 文 件 分 别 在 两 台 计 算 机 上 运 行 这 两 台 计 算 机 必 须有 固 定 的 IP 地 址 也 可 以 把 此 程 序 在 单 机 上 调 试 即 使 该 计 算 机 没 有 联 入In te rn e t 单 机 调 试 时 单 击 按 钮 后 在 A ddre s s N a m e 框 内 键 入
lo c a lh o s t 如 图 7 .2 所 示
图 7 .2 键 入 服 务 器 的 主 机 名
至 于 为 什 么 要 键 入 lo c a lh o s t 读 者 可 以 打 开 位 于 W ind ow s 目 录 的
HOS T S .S AM 文 件 那 里 为 IP 地 址 127 .0 .0 .1 定 义 了 主 机 名 为 lo c a lh o s t