博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++网络编程(二)--客户端服务器程序
阅读量:7235 次
发布时间:2019-06-29

本文共 2729 字,大约阅读时间需要 9 分钟。

这是一个基于windows的,用C++编写的客户端服务器程序,适合初学者,高手误入.

思路是这样的.启动服务器,服务器启动后会创建一个子线程,用于向客户端发送信息.用一个死循环用于接收客户端的请求,客户端请求成功后,会将客户端的连接保存到一个集合中,下面会详细介绍这个保存客户端连接的类.客户端连接成功后,服务器会创建一个子线程用于接收客户端的信息,客户端同样也会创建一个子线程接收服务器的信息.这样客户端和服务器就能进行通讯,如果有哪一方退出,另一方对应的接收数据的线程就会自动终止.

退出一个客户端后,服务器对应的接收数据的线程自动终止.如下图:

服务器保存客户端连接的集合中会删除对应的客户端连接,由于这个删除操作是在子线程中发生的,也就是说会有多个线程操作这个集合,那么针对这个集合的操作必须是线程安全的.保证线程安全的方法又很多,我的这篇博客《》介绍了5中方法实现线程同步,我这里用的是关键段,还有一点值得说明的是,保存客户端连接的集合肯定只能有一份,我用一个类封装了这个集合,这个类中的每个方法都是线程安全的,且只能有一个实例,这里用了比较暴力的方法,将相关的方法设为private,提供一个public的方法返回这个对象的一个静态实例,唯一的一个实例。

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

//ClientList.h 存放客户端的请求,只能有一个实例#ifndef _CLIENTLIST_H_#define _CLIENTLIST_H_#include 
#include "CSocket.h" #include
class CSocket;class ClientList{public : typedef vector
::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
_list; ClientList(); ClientList(const ClientList&); ClientList& operator=(const ClientList&); }; #endif
#include "ClientList.h"typedef vector
::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
ClientList::_list ;

转载于:https://www.cnblogs.com/hlxs/archive/2013/05/19/3087036.html

你可能感兴趣的文章
Memcachedclientutils类
查看>>
struts2注解总结----@Action和@Result
查看>>
Hadoop and Big Data
查看>>
Codeforces#86D Powerful array(分块暴力)
查看>>
Fault Diagnosability Infrastructure Overview
查看>>
Asp.Net Core使用Nginx实现反向代理
查看>>
C#分割字符串并统计重复出现的次数
查看>>
iOS UI 21 消息通知
查看>>
Unix环境高级编程(十八)高级进程间通信
查看>>
武汉科技大学ACM :1003: 零起点学算法67——统计字母数字等个数
查看>>
Hadoop_19_MapReduce&&Yarn运行机制
查看>>
C#里的一些关键字, sealed, abstract, virtual, override...
查看>>
作业-继承4
查看>>
图片放大和缩小
查看>>
六、Django模型基础第一节
查看>>
好好的,过了一两天,MyEclipse 不能正常运行了。。。
查看>>
SpringLayout的使用
查看>>
C#正则表达式大全
查看>>
hdu5901 Count primes(大素数模版)
查看>>
python入门(八):文件操作
查看>>