学习笔记二,vc++创建多线程服务器(二)

来源:互联网 发布:乌鲁木齐网络赛 编辑:程序博客网 时间:2024/04/27 20:49

休说鲈鱼堪脍,尽西风季鹰归未?

接下来让我们继续说道:启动服务。

启动服务器-->创建释放资源线程和接收客户端请求线程(设置bServerRuning = TRUE;表示服务器启动)。

-->A.创建释放资源线程(若失败则 bServerRunning = FALSE;表示服务器结束)

-->B.创建接收客户端请求线程(若失败则 bServerRunning = FALSE;表示服务器结束


释放资源线程中分为两种状态

一.当服务器正在运行(bServerRuning = TRUE)

这种情况主要是为了释放那些曾经连在服务器上的客户端线程,当他们退出时,来释放他们的资源。主要描述的是,客户端主动与服务器端断开连接,服务器端来释放资源的情况。

for(;bServerRunning;)//服务器正在运行{EnterCriticalSection(&csClientList);//清理已经断开的连接客户端内存空间CLIENTLIST::iterator iter = clientlist.begin();for(iter; iter != clientlist.end();){CClient *pClient = (CClient*)*iter;if(pClient -> IsExit())//客户端已经退出{clientlist.erase(iter++);delete pClient;pClient = NULL;}else{iter++;}}LeaveCriticalSection(&csClientList);Sleep(TIMEFOR_THREAD_HELP);}

二. 服务器即将退出

这种情况主要描述的是,服务器主动退出连接,释放资源的情况。这样就有两种情况,一是客户端还在与服务器连接,二是客户端没有与服务器连接

一。先断开客户端与服务器的连接。

//断开每个连接,线程退出EnterCriticalSection(&csClientList);CLIENTLIST::iterator iter = clientlist.begin();for(iter;iter != clientlist.end();){CClient *pClient = (CClient*)*iter;//如果客户端的连接还存在,则断开连接,线程退出if(pClient -> IsConning()){pClient->DisConning();}++iter;}//离开临界区LeaveCriticalSection(&csClientList);
//给连接客户端线程时间,使其自动退出Sleep(TIMEFOR_THREAD_SLEEP);
二。收回为每个客户端分配的内存都回收。

//进入临界区EnterCriticalSection(&csClientList);//确保每个客户端分配的内存都回收//如果不加入while这层循环,可能存在这样的情况,当pClient->exit()时,该线程还没有退出。//那么就需要从链表开始部分重新判断while(0 != clientlist.size()){iter = clientlist.begin();for(iter; iter != clientlist.end();){CClient *pClient = (CClient*)*iter;if(pClient -> IsExit()){clientlist.erase(iter++);delete pClient;pClient = NULL;}else{iter++;}}//给连接客户端线程时间,使其自动退出Sleep(TIMEFOR_THREAD_SLEEP);}//离开临界区LeaveCriticalSection(&csClientList);
注意,在最后我们还设置一个非常重要的事件--hServerEvent(服务器退出事件句柄)。
clientlist.clear();SetEvent(hServerEvent);

二。创建接收客户端请求线程(是由bServerRunning控制的)

第一步:接收客户端sAccept = accept(sServer, (SOCKADDR*)&addrClient,&lenClient);

第二步:创建客户端对象,并加入链表,并启动客户端

CClient *pClient = new CClient(sAccept,addrClient);//创建客户端对象EnterCriticalSection(&csClientList);clientlist.push_back(pClient);//加入链表LeaveCriticalSection(&csClientList);pClient -> StartRuning();