1:
在用CSocket,CArchive,CSocketFile联系进行数据传送的时候,三者是怎么建立联系的?
如:CSocket *m_pSocket(当然还要创建套接字).
CSocektFile *m_pFile=new CSocketFile(m_pSocket);//这里是怎么发生关联的,这个构造函数做了什么事情?
CArchive m_pArIn=new CArchive(m_pFile,CArchive::load);//这里也是一样~同上~~
我不是很明白他们是怎么发生关联的
2:
当建立起联系的时候~就是说服务器有个CSocket 对象和一个客户端的CSocket 对象关联起来~
在上面的情况下,没有看见任何的Send()函数的调用,是怎么传递消息的 ??不关发送或接受消息,只要调用CMsg(这个类是我建立的消息函数,里面实现Serialize()函数)的Serialize()就可以。不知道怎么实现传递的(很迷茫呢)~而且每个类里面都没有CMsg的实例。
如接受函数:
pMsg->Serialize(*m_pArchiveIn);//接受消息的时候;pMsg->Serialize(*m_pArchiveOut);//
m_pArchiveOut->Flush();//发送消息的时候。(难道是这里以后马上调用Send()函数?自调用?迷茫);
哪位高人给讲下过程或原理~~谢谢~

解决方案 »

  1.   

    CSocektFile *m_pFile=new CSocketFile(m_pSocket);//这里是怎么发生关联的,这个构造函??/////////////////////////////////////////////////////////////////////////////
    // CSocketFileclass CSocketFile : public CFile
    {
    DECLARE_DYNAMIC(CSocketFile)
    public:
    //Constructors
    explicit CSocketFile(CSocket* pSocket, BOOL bArchiveCompatible = TRUE);// Implementation
    public:
    CSocket* m_pSocket;
    CSocketFile内部使用了个CSocket*,由其构造函数指定。
      

  2.   

    UINT CSocketFile::Read(void* lpBuf, UINT nCount)
    {
    ASSERT(m_pSocket != NULL); if (lpBuf == NULL)
    {
    AfxThrowInvalidArgException();
    } int nRead; if (!m_bArchiveCompatible)
    {
    int nLeft = nCount;
    PBYTE pBuf = (PBYTE)lpBuf; while(nLeft > 0)
    {
    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;
    } 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);

    if (lpBuf == NULL)
    {
    AfxThrowInvalidArgException();
    } int nWritten = m_pSocket->Send(lpBuf, nCount);
    if (nWritten == SOCKET_ERROR)
    {
    int nError = m_pSocket->GetLastError();
    AfxThrowFileException(CFileException::generic, nError);
    }
    }建议楼主读一下MFC相关的源代码。
      

  3.   

    void CArchive::Flush()
    {
    ASSERT_VALID(m_pFile);
    ASSERT(m_bDirectBuffer || m_lpBufStart != NULL);
    ASSERT(m_bDirectBuffer || m_lpBufCur != NULL);
    ASSERT(m_lpBufStart == NULL ||
    AfxIsValidAddress(m_lpBufStart, UINT(m_lpBufMax - m_lpBufStart), IsStoring()));
    ASSERT(m_lpBufCur == NULL ||
    AfxIsValidAddress(m_lpBufCur, UINT(m_lpBufMax - m_lpBufCur), IsStoring())); if (IsLoading())
    {
    // unget the characters in the buffer, seek back unused amount
    if (m_lpBufMax != m_lpBufCur)
    m_pFile->Seek(-(int(m_lpBufMax - m_lpBufCur)), CFile::current);
    m_lpBufCur = m_lpBufMax;    // empty
    }
    else
    {
    if (!m_bDirectBuffer)
    {
    // write out the current buffer to file
    if (m_lpBufCur != m_lpBufStart)
    m_pFile->Write(m_lpBufStart, ULONG(m_lpBufCur - m_lpBufStart));
    }
    else
    {
    // commit current buffer
    if (m_lpBufCur != m_lpBufStart)
    m_pFile->GetBufferPtr(CFile::bufferCommit, ULONG(m_lpBufCur - m_lpBufStart));
    // get next buffer
    VERIFY(m_pFile->GetBufferPtr(CFile::bufferWrite, m_nBufSize,
    (void**)&m_lpBufStart, (void**)&m_lpBufMax) == (UINT)m_nBufSize);
    ASSERT((UINT)m_nBufSize == (UINT)(m_lpBufMax - m_lpBufStart));
    }
    m_lpBufCur = m_lpBufStart;
    }
    }
    CArchieve::Flush调CSocketFile::Write,CSocketFile::Write调CSocket::Send(m_pSocket).
      

  4.   

    1 CSocket 是运用 Windows Socket API 函数来进行通讯,CArchive、CSocketFile等等不过是Socket API 函数的封装。平心而论,MFC 对网络通讯,尤其是 Socket API 的封装是相当失败的。因此你的疑问理所当然,建议你看一下<Windows网络编程>,会有所收获的。2 Serialize是序列化一个类的数据,CObject类或者其子类具有被序列化的能力。序列化以后,一个类的数据可以以标准输入输出流(就是iostream)的形式传递。
      

  5.   

    CSocket类的编程模式:
    (1)创建Socket
    ●服务器端程序:
    CSocketsockSrvr;
    sockSrvr.Create(nPort); //用指定端口创建套接字
    ●客户端程序:
    CSocketsockClient;
    sockClient.Create(); //用缺省的端口创建套接字
    (2)连接
    ●服务器端程序:
    sockSrvr.Listen(); 服务器端程序对指定连接端口进行监听
    CSockersockRecv; //创建一个空的CSocket对象
    sockSrvr.Accept(sockRecv); //接受客户端的连接请求
    ●客户端程序:
    sockClient.Connect(strAddr,nPort);//连接指定地址的服务器(参数strAddr中指定)
    (3)数据传输
    ●服务器端程序:
    CSocketFile file(&sockRecv);
    //创建与CSocket类的对象相连接的CSoeketFile类对象
    CArchive arin(&file,CArchive::load);
    //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储将要发送的数据
    CArchive arout(&file,CArchive::load);
    //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储接收的数据
    arin>>dwValue; //发送数据dwValue
    arout<<dwValue; //接收数据dwValue
    ●客户端程序:
    CSocketFile file(&sockClient);
    //创建与CSocket类的对象相连接的CSocketFile类对象
    CArchive arin(&file,CArchive::load);
    //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储将要发送的数据
    CArchive arout(&file,CArchive::load)
    //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储接收的数据
    arin>>dwValue; //发送数据dwValue
    arout<<dwValue; //接收数据dwValue
    (4) 网络通信结束后,对于在栈中创建的CSocket对象、CArchive对象、CSocketFile对象,如
    果对象超出定义的范围时将自动调用析构函数释放相关资源;对于在堆中创建的对象,需要调用delete
    操作销毁对象符释放相关资源。
    具体可见<<windows网络编程>>