§4.7客户端的底层通讯类的设计
与客户端上层的接口是CClientSocket类,它隐藏了服务器底层通讯的细节及多线程发送数据的问题,提供给上一层一个统一的接口,CClientSocket类的使用,是先建立一个它的实例,再调用成员函数Create()传入必要的参数,发送数据时,就调用其成员函数SendData,或SendDataInThread处理发送数据,在CRecvSocket类的OnReceive里处理,向父窗口发送一个WM_RECIEVE_MSG消息,并把接受到的数据作为参数传递给父窗口。两个函数的适应情况,SendData函数,适用于需要直接发送数据的场合,不需要回应。如果在线程里执行,则可由其返回值确定发送成功与否。而SendDataInThread是建立一个线程,在线程里调用SendData函数进行发送数据,通过向指定接受窗口发送消息来确定是否成功。
算法描述: 发送一个数据,需要等待响应信息的回来,如果在规定时间内,还没有收到确认信息,则认为发送数据丢失,将重试FailReDoTime次,如果还是没有确认信息发送回来,则返回发送失败,否则,返回发送成功。 因为客户端可以多线程的发送数据,有一个请求,就建立一个线程进行处理。我为每个发送socket设置一个是否忙的标志busy,当需要发送数据时,就选择一个空闲的sendsocket,设置为忙,然后发送数据,再设置回空闲,然后等待确认信息的回来。 SendData函数的实现算法,与服务器端是基本一样的原理,通过设置一个缓冲区长度为N,然后,为每一次数据进行统计,发一次,就加1,然后把发送数据中的This=count%N,且把缓冲区中第This个成员设为0,在发送端,就要数组中的第This个成员是否为1即可,在接受到的确认信息中,取出This项,再为缓冲区中第This项设为1,这样就可以快速且可靠的判断发送数据是否得到响应回来了。 因为在客户端,大部分数据,是在某个消息处理函数中执行的,所以,适用于服务器的SendData发送数据函数,在客户端,若是在消息处理函数中发送,函数返回值,将永远为FALSE,于是就添加了一个SendDataInThread函数,把发送数据的过程放在线程里执行,通过发消息的手段,来返回结果。在SendDataInThread函数中,调用SendData函数进行发送数据。
客户端通讯类的结构: class CClientSocket : public CAsyncSocket { public: CClientSocket(); virtual ~CClientSocket(); void SendDataInThread(CData* pData,CWnd*pWnd); // 在线程里发送数据,成功,或失败都会向指定窗口类发送一个WM_SENDINTHREAD_RES 的消息,参数WPARAM为发送数据的指针,参数LPARAM为1,则表示发送成功,0则表示发送失败 BOOL Create(int TimeOut=TimeWaitForRes); //建立SOCKET BOOL SendData(CData* pData,int FailReDoTimes=3); //发送数据成员函数,失败重试指定的FailReDoTimes次,成功返回真 CWnd* GetOwner(){return m_pWnd;}; //得到接受发来数据的处理窗口指针 void SetOwner(CWnd* pWnd){m_pWnd=pWnd;}; //设置接受发来数据的处理窗口指针 virtual void OnReceive(int nErrorCode);处理FD_READ网络事件 private: CWnd* m_pWnd; //接受发来数据的处理窗口指针 char m_szResponseMsg[MaxResponseMsgLength]; int m_szrLength; BOOL m_bBusy; //是否处理忙状态 BYTE m_arBuf[CheckBufLength];//检查确认信息的缓冲数组 DWORD m_nTotalSend; //从启动到现在为此,发送的数据总数 DWORD m_nTimeOut; //发送数据的超时时间 };
§4.8客户/服务器之间的通讯的数据类的设计
整个系统的所有的发送的数据,都包含在这
首页 上一页 6 7 8 9 10 11 12 下一页 尾页 9/17/17