Windows 套接字:对存档使用套接字

本文介绍 CSocket 编程模型。 类 CSocket 提供比类 CAsyncSocket 抽象级别更高的套接字支持。 CSocket 使用 MFC 序列化协议版本通过 MFC CArchive 对象将数据传递到套接字对象并从该对象传递数据。 CSocket 提供锁定(在管理对 Windows 消息的背景处理时)并为您提供对 CArchive 的访问权限(其将管理您必须使用原始 API 或类 CAsyncSocket 亲自进行的通信的多个方面)。

提示

您可以单独使用类 CSocket 作为 CAsyncSocket 的更方便的版本,但最简单的编程模型是使用具有 CSocket 对象的 CArchive

有关使用存档实现套接字的详细信息,请参阅 Windows 套接字:使用存档的套接字的工作原理。 有关示例代码,请参阅 Windows 套接字:操作序列Windows 套接字:使用存档的套接字示例。 有关可通过从套接字类派生自己的类来获取的部分功能的信息,请参阅 Windows 套接字:从套接字类派生

注意

如果您要编写 MFC 客户端程序来与建立的(非 MFC)服务器通信,则请勿通过存档发送 C++ 对象。 除非服务器是知道您要发送的对象类型的 MFC 应用程序,否则它无法接收和反序列化对象。 有关与非 MFC 应用程序通信的主题的相关材料,另请参阅文章 Windows 套接字:字节排序

CSocket 编程模型

使用 CSocket 对象涉及创建多个 MFC 类对象并将这些对象相关联。 在下面一般过程中,每个步骤均由服务器套接字和客户端套接字执行,步骤 3 除外,该步骤中每个套接字类型都需要不同的操作。

提示

在运行时,当客户端应用程序寻求连接时,服务器应用程序通常将先开始准备好并“侦听”。 如果服务器在客户端尝试连接时未准备就绪,则您通常需要用户应用程序之后再次尝试连接。

在服务器套接字和客户端套接字之间设置通信

  1. 构造 CSocket 对象。

  2. 使用对象创建基础 SOCKET 句柄。

    对于 CSocket 客户端对象,正常情况下应使用默认参数创建,除非需要数据报套接字。 对于 CSocket 服务器对象,必须在 Create 调用中指定端口。

    注意

    CArchive 不适用于数据报套接字。 如果要将 CSocket 用于数据报套接字,则必须如在没有存档的情况下使用 CAsyncSocket 一样使用此类。 由于数据报是不可靠的(不能保证到达并且可能重复或离开序列),因此它们将不能通过存档与序列化兼容。 您期待序列化操作可靠且有序地完成。 如果您尝试对数据报使用带 CSocket 对象的 CArchive,则 MFC 断言将失败。

  3. 如果套接字是客户端,则请调用 CAsyncSocket::Connect 将套接字对象连接到服务器套接字。

    - 或者 -

    如果套接字是服务器,则请调用 CAsyncSocket::Listen 开始侦听客户端的连接尝试。 在收到连接请求之后,通过调用 CAsyncSocket::Accept 接受请求。

    注意

    Accept 成员函数会引用一个新的空 CSocket 对象作为其参数。 必须先构造此对象,然后才能调用 Accept。 如果此套接字对象超出范围,则关闭连接。 请勿为此新的套接字对象调用 Create

  4. 创建一个 CSocketFile 对象,将 CSocket 对象与之关联。

  5. 创建一个 CArchive 对象来加载(接收)或存储(发送)数据。 存档将与 CSocketFile 对象关联。

    记住,CArchive 不适用于数据报套接字。

  6. 使用 CArchive 对象在客户端套接字和服务器套接字之间传递数据。

    记住,给定 CArchive 对象将仅按一个方向移动数据:进行加载(接收)或存储(发送)。 在某些情况下,您将使用两个 CArchive 对象:一个用于发送数据,另一个用于接收确认。

    在接受连接并设置存档之后,你可以执行类似验证密码的任务。

  7. 销毁存档、套接字文件和套接字对象。

    注意

    CArchive 提供专门用于类 IsBufferEmptyCSocket 成员函数。 例如,如果缓冲区包含多条数据消息,则您需要循环至读取所有这些消息并清除缓冲区。 否则,可能无限期延迟指示有数据要接收的下一条通知。 使用 IsBufferEmpty 确保检索所有数据。

Windows 套接字:操作顺序一文演示了此过程的两方面,其中包含示例代码。

有关详细信息,请参阅:

另请参阅

MFC 中的 Windows 套接字
CSocket::Create