Windows 套接字:将套接字与存档配合使用

本文介绍 CSocket 编程模型。 类 CSocket 在抽象级别高于 类 CAsyncSocket 提供套接字支持。 CSocket 使用 MFC 序列化协议的版本通过 MFC CArchive 对象传入和传出套接字对象的数据。 CSocket 提供阻止(同时管理 Windows 消息的后台处理)并授予你访问权限 CArchive,这将管理你必须使用原始 API 或类 CAsyncSocket自行完成的通信的许多方面。

小窍门

可以将类CSocket本身用作更方便的版本CAsyncSocket,但最简单的编程模型是与对象一CSocketCArchive起使用。

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

注释

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

CSocket 编程模型

CSocket使用对象涉及创建和关联多个 MFC 类对象。 在下面的常规过程中,服务器套接字和客户端套接字均执行每个步骤,但步骤 3 除外,其中每个套接字类型都需要不同的作。

小窍门

在运行时,服务器应用程序通常会在客户端应用程序查找连接时先开始准备并“侦听”。 如果客户端尝试连接时服务器未准备就绪,通常要求用户应用程序稍后重试连接。

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

  1. 构造 CSocket 对象。

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

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

    注释

    CArchive 不适用于数据报套接字。 如果要 CSocket 用于数据报套接字,则必须像使用一样使用 CAsyncSocket类,即不使用存档。 由于数据报不可靠(不能保证到达并可能重复或无序),因此它们与通过存档进行序列化不兼容。 你希望序列化作能够可靠且按顺序完成。 如果尝试对CArchive数据报的对象使用CSocket,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 提供 IsBufferEmpty 专门用于类 CSocket的成员函数。 例如,如果缓冲区包含多个数据消息,则需要循环,直到读取所有这些消息并清除缓冲区。 否则,下一个通知指出接收的数据可能会无限期延迟。 用于 IsBufferEmpty 确保检索所有数据。

Windows 套接字:作序列用示例代码阐释了此过程的两侧。

有关详细信息,请参见:

另请参阅

MFC 中的 Windows 套接字
CSocket::Create