在 Windows 下的 socket 编程有两个编程模型,阻塞和非阻塞。有时,他们也被叫做同步(阻 塞)和异步(非阻塞)。
在 Unix 中只支持阻塞模型。
实际上还 有些 其他的 已经实 现的模 型。 包括完 成端口 (completion ports), 和重叠 I/O(overlapped I/O) 。然而使用这些模型要用明显更多的代码并且它们是特别为高级服务器 应用保留的。
还有,这些模型不跨平台并且在不同平台的实现方式和实现程度不同。 Indy 10 包含对这些其他模型的支持。阻塞
Indy 使用阻塞 socket 调用。阻塞调用很像一个文件的读写。当你读数据或者写数据时,直 到操作完成,函数才会返回。不同的是,socket 中,操作可能会消耗更久因为数据可能不能 立即读写。一个读或写操作的速度无法超过网络或模型接收和传输数据的速度。使用 Indy 时,连接一个接口只要简单的调用 Connect 方法,然后等待它返回。如果 Connect 成功,它会在连接后返回。如果 Connect 方法失败,它会引发相应的异常
非阻塞
非阻塞 socket 使用事件机制。调用被触发后,当他们完成或者需要被注意时,引发事件。 比如,当尝试连接一个 socket 时,你必须调用 Connect 方法。Connect 方法在 Socket 连接前 就立即会返回值。当 socket 连接上了,一个事件会发生。这要求通信逻辑被分成许多程序, 或者使用轮询循环(polling loops)。阻塞的优点
1. 易于编程 — 阻塞 socket 很易于编程。所有的用户代码都在一个地方,并且顺序排列。 2. 跨平台 — 由于 Unix 使用阻塞 socket,便携式代码很好写。Indy 依靠这个事实来实现 它的单源代码跨平台能力。其他跨平台的 socket 组件通过内部使用阻塞调用来模拟非 阻塞行为。 3. 多线程工作良好 — 由于阻塞 socket 的使用按照自然顺序,他们是可继承的封装,因 此很适合多线程。 4. 不依赖消息 — 非阻塞 socket 依赖于 window 信息系统。当在多线程中使用时,分别的 信息序列要被创建。当不在多线程中使用时,处理多链接时很容易发生瓶颈情况。阻塞的缺点
客户端用户界面"冻结" — 阻塞 socket 调用后直到完成任务才会返回。当这调用发生在应用 的主线程中时,主线程无法处理用户界面消息。这导致用户界面的"冻结"。冻结的发生是由 于直到阻塞 socket 调用返回控制应用程序的句柄前,更新,重绘和其他消息都无法被处理。非阻塞的优点
1. 客户端无用户界面"冻结" — 因为用户代码响应事件,Windows 在 socket 事件间拥有 控制权。因此,Windows 也可以答复其他 Windows 消息。 2. 可以不用多线程的多任务 — 单线程可以处理许多 socket。 3. 许多 socket 是轻量级的 — 因为许多 socket 可以被处理而不需要多线程,内存和 CPU 的占用通常很少。非阻塞的缺点
编程更难 — 非阻塞要求使用轮询或者事件。由于轮询很没效率,事件更常用。使用事件要 求用户代码分成许多子过程因此需要状态追踪。这导致代码易于出 bug 并且难以维护。