MFC教程(14)-- SOCKET类的设计和实现
2010-03-28 20:34:56 来源:WEB开发网下面,分析CSocketFile的设计和实现。
CSocketFile的构造函数和析构函数的实现
构造函数的实现
CSocketFile::CSocketFile(CSocket* pSocket, BOOL bArchiveCompatible)
{
m_pSocket = pSocket;
m_bArchiveCompatible = bArchiveCompatible;
#ifdef _DEBUG
ASSERT(m_pSocket != NULL);
ASSERT(m_pSocket->m_hSocket != INVALID_SOCKET);
int nType = 0;
int nTypeLen = sizeof(int);
ASSERT(m_pSocket->GetSockOpt(SO_TYPE,&nType,&nTypeLen));
ASSERT(nType == SOCK_STREAM);
#endif // _DEBUG
}
其中:
构造函数的参数1指向关联的CSocket对象,被保存在成员变量m_pSocket中;
参数2指定该对象是否和一个CArchive对象关联(不关联则独立使用),被保存在成员变量bArchiveCompatible中。
Degug部分用于检测m_pSocket是否是SOCK_STREAM类型。
析构函数的实现
CSocketFile::~CSocketFile()
{
}
(2)CSocketFile的读写的实现
分析CSocketFile如何用文件的读写实现网络I/O。
文件读的实现
UINT CSocketFile::Read(void* lpBuf, UINT nCount)
{
ASSERT(m_pSocket != NULL);
int nRead;
//CSocketFile对象独立使用
if (!m_bArchiveCompatible)
{
int nLeft = nCount;
PBYTE pBuf = (PBYTE)lpBuf;
//读完nCount个字节的数据
while(nLeft > 0)
{
//CSocket的Receive,阻塞操作,读取到数据才继续
nRead = m_pSocket->Receive(pBuf, nLeft);
if (nRead == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
ASSERT(FALSE);
}
else if (nRead == 0)
{
return nCount - nLeft;
}
nLeft -= nRead;
pBuf += nRead;
}
return nCount - nLeft;
}
//和一个CArchive对象关联使用
//读取数据,能读多少是多少
nRead = m_pSocket->Receive(lpBuf, nCount, 0);
if (nRead == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
ASSERT(FALSE);
}
return nRead;
}
文件写的实现
void CSocketFile::Write(const void* lpBuf, UINT nCount)
{
ASSERT (m_pSocket!=NULL);
//CSocket的函数Send,阻塞操作,发送完毕才继续
int nWritten = m_pSocket->Send(lpBuf, nCount);
if (nWritten == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
}
}
从CSockefFile的读写实现可以看出,CSocketFile如果独立使用,在Read操作时可能出现无限等待,因为数据是分多个消息多次送达的,没有读取到指定长度的数据并不表示数据读取完毕。但是和CArchive配合使用,则仅仅读取到数据就返回。至于数据是否读取完毕,可以使用CArchive的IsBufferEmpty函数来判断。
其他CFile界面,CSocketFile没有实现。
从CScocketFile的设计和实现来看,CSocketFile是使用CSocket的一个很好的例子,也是使用CFile的一个例子。
更多精彩
赞助商链接