本文和两篇配套文章介绍了 Windows 套接字编程中的几个问题。 本文介绍阻止。 文章介绍了其他问题 :Windows 套接字:字节排序 和 Windows 套接字:转换字符串。
如果使用或派生自 类 CAsyncSocket,则需要自行管理这些问题。 如果使用或派生类 CSocket,MFC 会为你管理它们。
阻塞
套接字可以处于“阻止模式”或“非阻止模式”。阻止(或同步)模式下的套接字函数在完成作之前不会返回。 这称为阻塞,因为调用其函数的套接字在调用返回之前无法执行任何作(被阻止)。 例如,对 Receive
成员函数的调用可能需要一段时间才能完成,因为它等待发送应用程序发送(这是如果使用 CSocket
,或者与阻塞一 CAsyncSocket
起使用)。
CAsyncSocket
如果对象处于非阻止模式(异步作),则调用会立即返回,并且当前错误代码(使用 GetLastError 成员函数进行检索)为 WSAEWOULDBLOCK,指示调用因模式未立即返回而阻止调用。 (CSocket
从不返回 WSAEWOULDBLOCK。该类管理阻止。
套接字的行为在 32 位和 64 位作系统(如 Windows 95 或 Windows 98)下的行为不同于 16 位作系统(如 Windows 3.1)。 与 16 位作系统不同,32 位和 64 位作系统使用抢占式多任务并提供多线程处理。 在 32 位和 64 位作系统下,可以将套接字置于单独的工作线程中。 线程中的套接字可以阻止,而不会干扰应用程序中的其他活动,并且无需在阻塞上花费计算时间。 有关多线程编程的信息,请参阅 多线程处理一文。
注释
在多线程应用程序中,可以使用阻止性质 CSocket
来简化程序的设计,而不会影响用户界面的响应能力。 通过处理主线程中的用户交互和 CSocket
备用线程中的处理,可以分隔这些逻辑作。 在不是多线程的应用程序中,必须将这两个活动合并并处理为单个线程,这通常意味着使用 CAsyncSocket
此方法,以便按需处理通信请求,或在长时间同步活动期间重写 CSocket::OnMessagePending
以处理用户作。
此讨论的其余部分适用于面向 16 位作系统的程序员:
通常,如果使用 CAsyncSocket
,应避免使用阻塞作并改为异步作。 在异步作中,从调用Receive
后收到 WSAEWOULDBLOCK 错误代码的点,等到OnReceive
调用成员函数通知你可以再次阅读。 异步调用是通过回调套接字的相应回调通知函数(如 OnReceive)进行的。
在 Windows 下,阻止调用被视为不良做法。 默认情况下, CAsyncSocket 支持异步调用,必须使用回调通知自行管理阻止。 另一方面 ,CSocket 类是同步的。 它泵送 Windows 消息并管理阻止。
有关阻止的详细信息,请参阅 Windows 套接字规范。 有关“打开”函数的详细信息,请参阅 Windows 套接字:套接字通知 和 Windows 套接字:派生自套接字类。
有关详细信息,请参见: