Windows 套接字:锁定

本文和两篇配套文章介绍了 Windows 套接字编程中的若干问题。 本文包含锁定。 文章中涉及的其他问题:Windows 套接字:字节排序Windows 套接字:转换字符串

如果使用类 CAsyncSocket 或从其派生,则需要自行管理这些问题。 如果使用类 CSocket 或从其派生,则将由 MFC 管理这些问题。

阻塞

套接字可以处于“阻塞模式”或“非阻塞模式”。处于阻塞(或同步)模式的套接字的函数直到可完成其操作才会返回。 这称为“锁定”,因为调用其函数的套接字无法执行任何操作 - 在调用返回之前处于锁定状态。 例如,调用 Receive 成员函数的完成时间可能不确定,因为它将等待发送应用程序发送(前提是使用 CSocketCAsyncSocket 时出现阻塞)。 如果 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 套接字规范。 有关“On”函数的详细信息,请参阅 Windows 套接字:套接字通知Windows 套接字:从套接字类派生

有关详细信息,请参阅:

另请参阅

MFC 中的 Windows 套接字
CAsyncSocket::OnSend