多客户端服务器网络编程
来源:互联网 发布:淘宝天猫评价提取工具 编辑:程序博客网 时间:2024/06/09 05:35
这是一个基于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 ;
0 0
- 多客户端服务器网络编程
- 网络编程,服务器客户端
- java 网络编程 多个客户端连接服务器
- 网络编程 一个服务器同时为多个客户端服务
- java网络编程基于TCP的多客户端连接服务器
- java网络编程Socket单服务器与多客户端
- c++ 网络编程 socket 聊天客户端/服务器
- 网络编程基础(服务器,客户端)
- 网络编程之tcp服务器/客户端模型
- java网络编程之简单客户端服务器
- iOS网络编程1-客户端和服务器
- 网络编程 客户端与服务器数据传输
- 简单的网络编程--服务器,客户端呼应
- Linux 网络编程 基本服务器-客户端
- 网络编程客户端向服务器上传文件
- C++网络编程(二)--客户端服务器程序
- python网络编程服务器与客户端
- Linux网络编程[UDP客户端服务器的编程模型]
- C 面试题选(一)
- VC++6.0的那点事儿
- 1089 -- 寻找幸运数
- python 有关super
- Ubuntu 源码安装 odoo 8.0
- 多客户端服务器网络编程
- 1090 -- 简单编码
- restClient图解
- 1091 -- 逆反A*B
- Python week0
- Windows 2003密码重置
- 1092 -- 整数变换问题
- 1093 -- 一种排序
- leveldb学习:Cache