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);//进入关键段
for(int i=_list.size()-1;i>=0;i--)
{
_list[i];
}
_list.clear();
LeaveCriticalSection(&g_cs);//退出关键段
}
CRITICAL_SECTION ClientList::g_cs;
vector<CSocket> ClientList::_list ;
C++收集编程(一)
彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》
这是一个基于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);//进入关键段
for(int i=_list.size()-1;i>=0;i--)
{
_list[i];
}
_list.clear();
LeaveCriticalSection(&g_cs);//退出关键段
}
CRITICAL_SECTION ClientList::g_cs;
vector<CSocket> ClientList::_list ;
C++收集编程(一)
彼此相爱,却不要让爱成了束缚:不如让它成为涌动的大海,两岸乃是你们的灵魂。互斟满杯,却不要同饮一杯。相赠面包,却不要共食一个。一起歌舞欢喜,却依然各自独立,相互交心,却不是让对方收藏。因为唯有生命之手,方能收容你们的心。站在一起却不要过于靠近。—— 纪伯伦《先知》