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::Serialize
。 SerializeRaw
函数希望文件对象具有 CSocketFile
没有的函数,例如 Seek
。
当将 CArchive
与 CSocketFile
和 CSocket
一起使用时,可能会遇到 CSocket::Receive
进入循环(通过 PumpMessages(FD_READ)
)等待请求的字节数的情况。 这是因为 Windows 套接字只允许每个 FD_READ 通知进行一次 recv 调用,但 CSocketFile
和 CSocket
允许每个 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。
继承层次结构
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 套接字:使用存档的套接字示例。