CSocketFile 类

用于通过 Windows 套接字在网络中发送和接收数据的 CFile 对象。

语法

class CSocketFile : public CFile

成员

公共构造函数

名称 描述
CSocketFile::CSocketFile 构造 CSocketFile 对象。

备注

可以为此将 CSocketFile 对象附加到 CSocket 对象。 还可以将 CSocketFile 对象附加到 CArchive 对象,简化通过 MFC 序列化发送和接收数据的过程,这也是惯常做法。

若要序列化(发送)数据,将数据插入存档,这调用 CSocketFile 成员函数以将数据写入 CSocket 对象。 若要反序列化(接收)数据,则从存档中提取数据。 这导致存档调用 CSocketFile 成员函数以从 CSocket 对象读取数据。

提示

除了照此使用 CSocketFile 外,还可以将其用作独立文件对象,就像对其基类 CFile 做的那样。 还可以与任何基于存档的 MFC 序列化函数一起使用 CSocketFile。 由于 CSocketFile 不支持所有 CFile 功能,因此某些默认 MFC 序列化函数不兼容 CSocketFile。 这对 CEditView 类尤其如此。 不应尝试使用 CEditView::SerializeRaw 通过附加到 CSocketFile 对象的 CArchive 对象来序列化 CEditView 数据;改而使用 CEditView::SerializeSerializeRaw 函数希望文件对象具有 CSocketFile 没有的函数,例如 Seek

当将 CArchiveCSocketFileCSocket 一起使用时,可能会遇到 CSocket::Receive 进入循环(通过 PumpMessages(FD_READ))等待请求的字节数的情况。 这是因为 Windows 套接字只允许每个 FD_READ 通知进行一次 recv 调用,但 CSocketFileCSocket 允许每个 FD_READ 进行多次 recv 调用。 如果在没有要读取的数据时获得 FD_READ,则应用程序挂起。 如果从未收到另一个 FD_READ,应用程序将停止通过套接字进行通信。

可以按如下所示解决此问题。 在 OnReceive 套接字类的方法中,当预期从套接字读取的数据超过一个 TCP 数据包的大小(网络介质的最大传输单元,通常至少为 1096 字节)时,在调用消息类的 Serialize 方法之前调用 CAsyncSocket::IOCtl(FIONREAD, ...)。 如果可用数据的大小小于所需,请等待接收所有数据,然后才启动读取操作。

在以下示例中,m_dwExpected 是用户期望接收的大致字节数。 假设你在代码中的其他位置声明它。

void CChatSocket::OnReceive(int nErrorCode)
{
   CSocket::OnReceive(nErrorCode);

   DWORD dwReceived;

   if (IOCtl(FIONREAD, &dwReceived))
   {
      if (dwReceived >= m_dwExpected) // Process only if you have enough data
         m_pDoc->ProcessPendingRead();
   }
   else
   {
      // Error handling here
   }
}

有关详细信息,请参阅 MFC 中的 Windows 套接字Windows 套接字:对存档使用套接字,以及 Windows 套接字 2 API

继承层次结构

CObject

CFile

CSocketFile

要求

afxsock.h

CSocketFile::CSocketFile

构造 CSocketFile 对象。

explicit CSocketFile(
    CSocket* pSocket,
    BOOL bArchiveCompatible = TRUE);

参数

pSocket
要附加到 CSocketFile 对象的套接字。

bArchiveCompatible
指定文件对象是否用于 CArchive 对象。 仅当希望以独立方式使用 CSocketFile 对象时才传递 FALSE,就像使用独立 CFile 对象一样,存在某些限制。 此标志更改附加到 CSocketFile 对象的 CArchive 对象如何管理其缓冲区进行读取。

备注

当对象超出范围或遭到删除时,该对象的析构函数取消自身与套接字对象的关联。

注意

还可以将 CSocketFile 用作没有 CArchive 对象的(有限)文件。 默认情况下,CSocketFile 构造函数的 bArchiveCompatible 参数为 TRUE。 这指定文件对象用于存档。 若要在不使用存档的情况下使用文件对象,将 FALSE 传入 bArchiveCompatible 参数

在“存档兼容”模式下,CSocketFile 对象提供更好的性能,并减少“死锁”的危险。当发送和接收套接字相互等待或等待常见资源时,会发生死锁。 如果 CArchive 对象像使用 CFile 对象那样使用 CSocketFile,出现这种情况。 借助 CFile,存档可以假定它接收的字节数少于请求的字节数,则已达文件末尾。

但是借助 CSocketFile,数据是基于消息的;缓冲区可以包含多个消息,因此接收的字节数少于请求的字节数不意味着到达文件末尾。 这种情况下应用程序不会受阻,因为借助 CFile,它可以继续从缓冲区读取消息,直到缓冲区为空。 这种情况下 CArchive::IsBufferEmpty 函数可用于监视存档缓冲区的状态。

有关使用 CSocketFile 的详细信息,请参阅文章 Windows 套接字:对存档使用套接字,以及 Windows 套接字:使用存档的套接字示例

另请参阅

CFile 类
层次结构图
CAsyncSocket 类
CSocket 类