C++收集编程(二)--客户端办事器法度

    添加时间:2013-5-20 点击量:

    这是一个基于windows的,用C++编写的客户端办事器法度,合适初学者,高手误入.源码必共享



    思路是如许的.启动办事器,办事器启动后会创建一个子线程,用于向客户端发送信息.用一个死轮回用于接管客户端的恳求,客户端恳求成功后,会将客户端的连接保存到一个凑集中,下面会具体介绍这个保存客户端连接的类.客户端连接成功后,办事器会创建一个子线程用于接管客户端的信息,客户端同样也会创建一个子线程接管办事器的信息.如许客户端和办事器就能进行通信,若是有哪一方退出,另一方对应的接管数据的线程就会主动终止.



    退出一个客户端后,办事器对应的接管数据的线程主动终止.如下图:



    办事器保存客户端连接的凑集中会删除对应的客户端连接,因为这个删除操纵是在子线程中产生的,也就是说会有多个线程操纵这个凑集,那么针对这个凑集的操纵必须是线程安然的.包管线程安然的办法又很多,我的这篇博客《多线程编程--5种办法实现线程同步》介绍了5中办法实现线程同步,我这里用的是关键段,还有一点值得申明的是,保存客户端连接的凑集必然只能有一份,我用一个类封装了这个凑集,这个类中的每个办法都是线程安然的,且只能有一个实例,这里用了斗劲暴力的办法,将相干的办法设为private,供给一个public的办法返回这个对象的一个静态实例,独一的一个实例。


    保存客户端连接的类如下:



    //ClientList.h 存放客户端的恳求,只能有一个实例
    
    #ifndef _CLIENTLIST_H_
    #define _CLIENTLIST_H_
    #include
    <vector>
    #include
    CSocket.h
    #include
    <assert.h>
    class CSocket;
    class ClientList
    {
    public :
    typedef vector
    <CSocket>::iterator Iter;

    void Add(CSocket socket);

    int Count() const;

    CSocket
    operator[](size_t index);

    void Remove(CSocket socket);

    Iter Find(CSocket
    socket);

    void Clear();

    static ClientList GetInstance()
    {
    static ClientList instance;
    return &instance;
    }

    ~ClientList();
    private:
    static CRITICAL_SECTION g_cs;
    static vector<CSocket> _list;
    ClientList();
    ClientList(
    const ClientList&);
    ClientList
    & operator=(const ClientList&);
    };

    #endif



    #include ClientList.h
    
    typedef vector
    <CSocket>::iterator Iter;

    ClientList::ClientList()
    {
    InitializeCriticalSection(
    &g_cs);//初始化g_cs的成员
    }

    ClientList::
    ~ClientList()
    {
    DeleteCriticalSection(
    &g_cs);//删除关键段
    }

    void ClientList::Add(CSocket socket)
    {
    if(socket!=NULL)
    {
    EnterCriticalSection(
    &g_cs);//进入关键段
    _list.push_back(socket);
    LeaveCriticalSection(
    &g_cs);//退出关键段
    }
    }

    int ClientList::Count() const
    {
    return _list.size();
    }

    CSocket
    ClientList::operator[](size_t index)
    {
    assert(index
    >=0 && index<_list.size());
    return _list[index];
    }

    void ClientList::Remove(CSocket socket)
    {
    Iter iter
    =Find(socket);
    EnterCriticalSection(
    &g_cs);//进入关键段
    if(iter!=_list.end())
    {
    iter;
    _list.erase(iter);
    }
    LeaveCriticalSection(
    &g_cs);//退出关键段
    }

    Iter ClientList::Find(CSocket
    socket)
    {
    EnterCriticalSection(
    &g_cs);//进入关键段
    Iter iter=_list.begin();
    while(iter!=_list.end())
    {
    if(iter==socket)
    {
    return iter;
    }
    iter
    ++;
    }
    LeaveCriticalSection(
    &g_cs);//退出关键段
    return iter;
    }

    void ClientList::Clear()
    {
    EnterCriticalSection(
    &g_cs);//进入关键段
    forint i=_list.size()-1;i>=0;i--
    {
    _list[i];
    }
    _list.clear();
    LeaveCriticalSection(
    &g_cs);//退出关键段
    }

    CRITICAL_SECTION ClientList::g_cs;
    vector
    <CSocket> ClientList::_list ;


    C++收集编程(一)

    彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
    分享到: