C++网络编程(二)--客户端服务器程序

原文地址为: 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())
{
delete
*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--)
{
delete _list[i];
}
_list.clear();
LeaveCriticalSection(
&g_cs);//退出关键段
}

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

C++网络编程(一)


转载请注明本文地址: C++网络编程(二)--客户端服务器程序

猜你喜欢

转载自blog.csdn.net/wangchaoqi1985/article/details/81585285