网站导航网学 原创论文 网站设计 最新系统 最新研究 原创论文 获取论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计下载 > VC与C++类别 > 正文

基于VC的网络寻呼软件

来源:http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 13/05/14

【编者按】网学网VC与C++类别频道为大家收集整理了“基于VC的网络寻呼软件“提供大家参考,希望对大家有所帮助!

QQ交谈客服咨询,网学网竭诚为您服务,本站永久域名:myeducs.cn

.6服务器端的底层通讯类的设计

 

为了使能及时响应用户的请求,当用户很多时,仍然能够适应要求,我把侦听与发送数据的Socket分开,并分别都建立了多个实例,

也就是说,支持多个端口的侦听,发送数据使用的是多个端口,我只对侦听端口感兴趣,对发送数据的端口不感兴趣,因为,发送端口是多少都无所谓。

 

CRecvSocketCsendSocket都是从CAsyncSocket类里继承而来,分别处理侦听请求各发送数据,在CServerSocket类里,定义了几个CRecvSocketCSendSocket对象的实例,通过CServerSocket类对内部进行组织和管理,提供给上层的接口是CServerSocket,它隐藏了服务器底层通讯的细节及多线程发送数据的问题,提供给上一层一个统一的接口,CServerSocket类的使用,是先建立一个它的实例,再调用成员函数Create(),传入必要的参数,发送数据时,就调用其成员函数SendData,处理接受数据,在CRecvSocket类的OnReceive里处理,调用了一个名为ProcessRecvData的线程函数,用户在这个线程函数里写上具体的处理代码

 

算法描述:

 

发送一个数据,需要等待响应信息的回来,如果在规定时间内,还没有收到确认信息,则认为发送数据丢失,将重试FailReDoTime次,如果还是没有确认信息发送回来,则返回发送失败,否则,返回发送成功。

 

因为服务器是多线程的发送数据,有一个请求,就建立一个线程进行处理。我为每个发送socket设置一个是否忙的标志busy,当需要发送数据时,就选择一个空闲的sendsocket,设置为忙,然后发送数据,再设置回空闲,然后等待确认信息的回来。

 

SendData函数的实现算法,通过设置一个缓冲区长度为N,然后,为每一次数据进行统计,发一次,就加1,然后把发送数据中的This=count%N,且把缓冲区中第This个成员设为0,在发送端,就要数组中的第This个成员是否为1即可,在接受到的确认信息中,取出This项,再为缓冲区中第This项设为1,这样就可以快速且可靠的判断发送数据是否得到响应回来了。

 

侦听类结构:

class CRecvSocket : public CAsyncSocket

{

private:

       char m_szResponseMsg[MaxResponseMsgLength];     确认消息串

       int m_szrLength;                                 确认消息串的长度

public:

       CRecvSocket();

       virtual ~CRecvSocket();

public:

       BOOL Create(int nPort);             指定端口号,建立一个侦听Socket

       virtual void OnReceive(int nErrorCode);  处理接受数据

};

 

发送数据的socket类结构

class CSendSocket : public CAsyncSocket

{

private:

       BYTE* pBuf; 

//指向CServerSocketm_arBuf缓冲区,处理发送后是否收到确认信息的缓冲区

       char m_szResponseMsg[20];

       int m_szrLength;

public:

       CSendSocket(BYTE*buf);

       virtual ~CSendSocket();

       BOOL Create();                     建立一个发送的socket

       virtual void OnReceive(int nErrorCode);  处理发送数据后接受到的确认消息

};

 

服务器的socket

这个通讯类的SendData,当发送数据失败时,可以重发几次,次数可由用户来确定

class CServerSocket 

{

public:    

       void Close();

       BOOL Create(int SendSockNum,CArray<DWORD,DWORD>&aPort,int TimeOut= TimeWaitForRes);

//建立侦听Socket和发送SocketaPort是侦听端口数组,TimeOut是设置发送超时时间

       BOOL SendData(CData* pData,int FailReDoTimes=3);  

//数据函数,这个函数适合在线程里发送数据函数,而服务器的响应都是在工人线程里完成的,所以,很适合服务器的发送数据。成功返回真,不成功返回假

       CServerSocket();

       virtual ~CServerSocket();

private:

       CRecvSocket* m_apRecvSocket[ListenSocketNum];   侦听Socket的指针数组

       CSendSocket* m_apSendSocket[SendSocketNum];    发送Socket的指针数组

       int m_nRecvSocket;                       侦听Socket的个数

       int m_nSendSocket;                       发送Socket的个数

       BOOL m_abBusy[SendSocketNum];         标志每个发送Socket是否处于忙的状态

       BYTE m_arBuf[CheckBufLength];  检查发送数据发回的确认的缓冲数组

       DWORD m_nTotalSend;        保存从CserverSocket建立后,发送了多少次数据

       DWORD m_nTimeOut;                   发送数据的超时时间

};

 

 

§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为发送数据的指针,参数LPARAM1,则表示发送成功,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客户/服务器之间的通讯的数据类的设计

 

       整个系统的所有的发送的数据,都包含在这几个类中了,当要发送一种数据,则先确定一个数据类,然后填入相应数据,再调用函数PackToBuf就可以把这些数据,存入szBuf的数组缓冲区中,num指示其长度,LoadFromBuf函数则是已知在缓冲区中数据,把各项的值,从缓冲区中提取出来。因为使用udp协议发送数据,sendtorecvfrom函数,只能处理串的发送和接受,所以,把数据压为串,和从串中恢复数据,是这些数据类所必须完成的功能。

 

算法描述:

定义的基类,提供了数据的一种统一的接口,其派生类再对其虚函数进行重载,实现相应的功能。在数据的打包过程中,对字符串的打包原理为:先存入串长度,再存入串。串的长度,采用的是2个字节的WORD类型,已经足够满足要求了。打包时,按照某一顺序,对其进行数据的存入串中,解开时,以相同的顺序进行还原即可。其中,类CModifyPersonPI的算法与其它类不大一样,因为它的成员中有一个位掩Mask成员,只有被选中的成员,才会打包入串。

 

本站发布的计算机毕业设计均是完整无错的全套作品,包含开题报告+程序+论文+源代码+翻译+答辩稿PPT

本文选自计算机毕业设计http://myeducs.cn
论文文章部分只是部分简介,如需了解更多详情请咨询本站客服!QQ交谈QQ3710167

原创论文

设为首页 | 加入收藏 | 论文首页 |原创论文 |
版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师