C++封装select模型

// SelectModule.h: interface for the CSelectModule class.
//
//

#if !defined(AFX_SELECTMODULE_H__E53730A1_AC83_4698_8E8A_27D6B3DDC5D9__INCLUDED_)
#define AFX_SELECTMODULE_H__E53730A1_AC83_4698_8E8A_27D6B3DDC5D9__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CSelectModule  
{
public:
	CSelectModule();
	~CSelectModule();
	
	int GetClientCount();
	SOCKET* GetClientSockAry();

	BOOL AddSock(SOCKET ClientSock);
	BOOL DeleteSock(int index);

	BOOL CreateSelectThread();
	void SetThreadState(BOOL bFlag);

	static int m_nAllClientSockCount;  //总的客户端数量
	static CRITICAL_SECTION m_CRitical_Section;

private:
	SOCKET m_ClientSocketAry[FD_SETSIZE];
	int m_nClientSockCount;            //当前socket的个数

	HANDLE m_hThread;
	BOOL m_bFlag;  

};

#endif // !defined(AFX_SELECTMODULE_H__E53730A1_AC83_4698_8E8A_27D6B3DDC5D9__INCLUDED_)
// SelectModule.cpp: implementation of the CSelectModule class.
//
//


#include "stdafx.h"
#include "SelectModule.h"


//
// Construction/Destruction
//


int CSelectModule::m_nAllClientSockCount = 0;  //总的客户端数量


CRITICAL_SECTION CSelectModule::m_CRitical_Section;


DWORD WINAPI SelectThreadProc(LPVOID lpParameter)
{
	CSelectModule *pSelectMoulde = (CSelectModule*)lpParameter;


	if( NULL != pSelectMoulde)
	{
		fd_set fdRead;
		timeval tv = {2 , 0};
		int nResult = 0;
		int nClientCount = 0;
		SOCKET *pClientSock = NULL;
		TCHAR szRecvBuf[4096] = "";


		while(true)
		{
			FD_ZERO(&fdRead);


			nClientCount = pSelectMoulde->GetClientCount();
			if( 0 == nClientCount) break; //当前无客户端连接


			pClientSock = pSelectMoulde->GetClientSockAry();
		
			for(int i = 0 ; i < nClientCount ; i++)
				FD_SET(pClientSock[i],&fdRead);
			
			nResult = select(0,&fdRead,NULL,NULL,&tv);//等待时间1秒
		
			if( 0 == nResult) continue;


			for(i = 0 ; i < pSelectMoulde->GetClientCount() ; i++)
			{
				if( FD_ISSET(pClientSock[i],&fdRead))
				{
					nResult = recv(pClientSock[i],szRecvBuf,4096,0);


					if( 0 == nResult || SOCKET_ERROR == nResult)
					{
						//客户端断开
						cout << "Client is Disconnect!" << pClientSock[i] << endl;	
						pSelectMoulde->DeleteSock(i);
						cout << "****************Current Client TotalCount:" << CSelectModule::m_nAllClientSockCount << "**********************"<<endl;
						i--;
					}
					else
					{
						szRecvBuf[nResult] = '\0';
						send(pClientSock[i],szRecvBuf,strlen(szRecvBuf) + 1,0);
					}
				}
			}
		}	
	}


	cout << " ++++++++++++++++++++++++++Thread Exit!++++++++++++++++++++++++++" << endl;
	pSelectMoulde->SetThreadState(FALSE);
	return 0;
}


CSelectModule::CSelectModule()
{
	m_nClientSockCount = 0;            //当前socket的个数
     
	m_bFlag = FALSE;                   //线程挂起
	//初始化线程将线程挂起
	m_hThread = NULL ;
}


CSelectModule::~CSelectModule()
{


}


BOOL CSelectModule::CreateSelectThread()
{
	m_hThread = CreateThread(NULL,0,SelectThreadProc,this,0,0);//创建线程时挂起
	cout << "+++++++++++++++++++++++++++++CreateThread+++++++++++++++++++++++++++" << endl;
	m_bFlag = TRUE;


	return FALSE;
}


void CSelectModule::SetThreadState(BOOL bFlag)
{
	m_bFlag = bFlag;
}


int CSelectModule::GetClientCount()
{
	return m_nClientSockCount;
}


SOCKET* CSelectModule::GetClientSockAry()
{
	return m_ClientSocketAry;
}


BOOL CSelectModule::AddSock(SOCKET ClientSock)
{
	if( INVALID_SOCKET != ClientSock)
	{
		::EnterCriticalSection(&CSelectModule::m_CRitical_Section);
		m_ClientSocketAry[m_nClientSockCount++] = ClientSock;
		m_nAllClientSockCount++;


		if( FALSE == m_bFlag) //线程未创建
		{	
			CreateSelectThread();
			cout << "Create is succeed!" << endl;
		}
		::LeaveCriticalSection(&CSelectModule::m_CRitical_Section);
	}


	return FALSE;
}


BOOL CSelectModule::DeleteSock(int index)
{
	if( index >= 0 && index < m_nClientSockCount)
	{
		::EnterCriticalSection(&CSelectModule::m_CRitical_Section);
		closesocket(m_ClientSocketAry[index]);
		m_ClientSocketAry[index] = m_ClientSocketAry[m_nClientSockCount - 1];
		m_nClientSockCount--;
		m_nAllClientSockCount--;
		::LeaveCriticalSection(&CSelectModule::m_CRitical_Section);
		return TRUE;
	}
	
	return FALSE;
}

BOOL CListenSock::AcceptSock()
{
      SOCKET ClientSock = NULL;
  
      CSelectModule SelectModuleAry[4];
      int nClientCount = 0;
      
      ::InitializeCriticalSection(&CSelectModule::m_CRitical_Section);


     while(true) 
    {
      ClientSock = accept(m_ListenSock,NULL,NULL);
     //投递socket
    if( CSelectModule::m_nAllClientSockCount > 200)continue;
         
    cout << "Client is Connect Succeed!" << endl;

    for(int i = 0 ; i < 4 ; i++) //先找启动的线程
    {
      nClientCount = SelectModuleAry[i].GetClientCount();

    if( nClientCount > 0 && nClientCount < FD_SETSIZE)
    {
     SelectModuleAry[i].AddSock(ClientSock);break;
    }
    }

   if( 4 == i) 
   {
    for( i = 0 ; i < 4 ; i++) //在创建新的线程
     {
       if( 0 == SelectModuleAry[i].GetClientCount())
       { 
         SelectModuleAry[i].AddSock(ClientSock);
         break;
      }
     }     
   }


    cout << "****************Current Client TotalCount:" << CSelectModule::m_nAllClientSockCount << "**********************"<<endl;}

return FALSE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值