⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multhreadsever.cpp

📁 一个网络监视的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 功能描述:监听是否有客户连接,若有则创建相应子线程去服务它
// 输入参数:char data[],char IP[],int first,int last
// 输出参数:void
// 创建日期:04-7-16
// 修改日期:
// 作      者:郑富强
// 附加说明:
//===============================================================
unsigned _stdcall ListenThread(void *pVoid)
{
	unsigned long ThreadAddr;
	client_thread_parameter par;
	HANDLE dwClientThread;
	SOCKADDR_IN SockAddr;
	int nLen;
	HANDLE hNoClients;
	LPHANDLE pExitEventHandle=(LPHANDLE)pVoid;
	hNoClients=InitClientCount();//初始化客户连接记数
	                             //hNoClients初始为无信号状态
	while(1)
	{
		nLen = sizeof(SOCKADDR_IN);
		par.socketClient = accept(listenSocket, (LPSOCKADDR)&SockAddr, &nLen);
		
		if ( par.socketClient == INVALID_SOCKET )
			break;

		strcpy(par.ClientIP,inet_ntoa(SockAddr.sin_addr));//IP获取
		CString strIP( par.ClientIP );	//客户端的IP地址;

// * * * * * * 陈欢插入的代码* 开始* * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * * * *
		extern CRITICAL_SECTION g_criActiveClientList;
		extern ActivClient theActiveClientList;
		extern CRITICAL_SECTION g_criNewAccess;
		extern bool bNewAccess;

		EnterCriticalSection( &g_criActiveClientList );
		EnterCriticalSection( &g_criNewAccess );

		int index = theActiveClientList.AddClient( strIP );

		// set modified
		bNewAccess = true;

		LeaveCriticalSection( &g_criNewAccess );
		LeaveCriticalSection( &g_criActiveClientList );

		DataToDB::AddClientData(strIP);
// * * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * 陈欢插入的代码* 结束* * * * * * * * * * * * * * * * * * *

		//创建一个独立的线程用来单独处理客户的请求
		dwClientThread=CreateThread(NULL,0,ClientThread,(void*)&par,0,&ThreadAddr);
	} // while (1)
    
	WaitForSingleObject((HANDLE)*pExitEventHandle,INFINITE);//等待结束事件
	WaitForSingleObject(hNoClients,5000000);//等待所有的客户线程结束
	DeleteClientCount();
	CloseHandle((HANDLE)gdwListenThread);
	return 0;
}

//===============================================================
// 函 数 名:ativity_dispatch
// 功能描述:监听是否有客户连接,并创建客户端线程去
// 输入参数:char data[],char IP[],int first,int last
// 输出参数:void
// 创建日期:04-7-16
// 修改日期:
// 作      者:郑富强
// 附加说明:
//===============================================================
unsigned long _stdcall ClientThread(void *pVoid)
{

	//客户连接服务子线程,独立地为每个客户的请求服务
	data DataPacket;
	client_thread_parameter* lppar=(client_thread_parameter*)pVoid;
	char ClientIP[16];
	SOCKET socketClient = lppar->socketClient;
	strcpy(ClientIP,lppar->ClientIP);
	IncrementClientCount();//增加客户连接个数
	
    while(1)
	{
	    if(recv(socketClient,(char*)&DataPacket,sizeof(DataPacket),0)<=0)
		{
// * * * * * * 陈欢插入的代码* 开始* * * * * * * * * * * * * * * * * * *
// * * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * * * *
			// 接收文件时发生错误, 说明客户端已经断开连接
			extern CRITICAL_SECTION g_criActiveClientList;
			extern ActivClient theActiveClientList;
			extern CRITICAL_SECTION g_criNewAccess;
			extern bool bNewAccess;

			EnterCriticalSection( &g_criActiveClientList );
			EnterCriticalSection( &g_criNewAccess );

			// 从活动主机列表中删除该主机
			theActiveClientList.RemoveClient( ClientIP );

			bNewAccess = true;	//修改标志

			LeaveCriticalSection( &g_criNewAccess );
			LeaveCriticalSection( &g_criActiveClientList );
// * * * * * * * * * * * * *  * * * * * * * * * * * * * * * * * * * * * *
// * * * * * * 陈欢插入的代码* 结束* * * * * * * * * * * * * * * * * * *

			break;	
		}
		int len=DataPacket.len,i=0;
	    int first=0;
	    while(i<=len)
		{
		    if(DataPacket.buff[i]!='\n'&&DataPacket.buff[i]!='\0')
			{
			    i++;
			}
		    else
			{
				if ( first < i-1 )
					ativity_dispatch(DataPacket.buff,ClientIP,first,i-1);
			    i++;
			    first=i;
			}
		}

	}
	closesocket(socketClient);
	DecrementClientCount();
	return 0;
}

//===============================================================
// 函 数 名:IncrementClientCount
// 功能描述:子线程数累加
// 输入参数:void
// 输出参数:void
// 创建日期:04-7-16
// 修改日期:
// 作      者:郑富强
// 附加说明:
//===============================================================
void IncrementClientCount(void)
{
	
	EnterCriticalSection(&gcriticalClients);
	gdwClientCount++;
	LeaveCriticalSection(&gcriticalClients);
	ResetEvent(ghNoClients);//将ghNoClients设置为无信号状态

}


//===============================================================
// 函 数 名:DecrementClientCount
// 功能描述:子线程数累减
// 输入参数:void
// 输出参数:void
// 创建日期:04-7-16
// 修改日期:
// 作      者:郑富强
// 附加说明:
//===============================================================
void DecrementClientCount(void)
{
	
	EnterCriticalSection(&gcriticalClients);
	if(gdwClientCount>0)
		gdwClientCount--;
	LeaveCriticalSection(&gcriticalClients);
	if(gdwClientCount<1)
		SetEvent(ghNoClients);//将ghNoClients设置为有信号状态

}


//===============================================================
// 函 数 名:DeleteClientCount
// 功能描述:清理子线程记数资源
// 输入参数:void
// 输出参数:void
// 创建日期:04-7-16
// 修改日期:
// 作      者:郑富强
// 附加说明:
//===============================================================
void DeleteClientCount(void)
{
	
	DeleteCriticalSection(&gcriticalClients);
	CloseHandle(ghNoClients);
}


// 此函数由 main 改名而得
void InitSocket()
{

	SOCKADDR_IN saServer;
//	unsigned long ThreadID;
	int nRet;
	StartSock(); //用来加载socket
	ghExit = CreateEvent(NULL, TRUE, FALSE, NULL); //人工重置,初始状态为false
	listenSocket = socket(AF_INET, SOCK_STREAM, 0);//创建一个主socket
	if ( ghExit==NULL || listenSocket==INVALID_SOCKET)
	{
//		if(ghExit==NULL)
//			AfxMessageBox("ghExit==NULL\n");
//		if(listenSocket==INVALID_SOCKET)
//			AfxMessageBox("listenSocket==INVALID_SOCKET\n");
		
		return;
	}

	saServer.sin_port=htons(ServerPort);
	saServer.sin_family=AF_INET;
	saServer.sin_addr.s_addr=INADDR_ANY;
	nRet=bind(listenSocket,(LPSOCKADDR)&saServer,sizeof(struct sockaddr));//将socket和本地地址绑定
	if(nRet==SOCKET_ERROR)
	{
//		AfxMessageBox("bind ERROR!\n");
		closesocket(listenSocket);
		return;
	}

	//////////////////////// 
	nRet = listen(listenSocket,SOMAXCONN);//设置为侦听状态
	if(nRet == SOCKET_ERROR)
	{
//		AfxMessageBox("Listen ERROR!\n");
		closesocket(listenSocket);
		return;
	}

	//创建主侦听线程
/*	gdwListenThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ListenThread,&ghExit,0,&ThreadID);
	if(!gdwListenThread)
	{
//		AfxMessageBox("!gdwListenThread\n");
		closesocket(listenSocket);
	}
*/
	WaitForSingleObject((HANDLE)gdwListenThread,INFINITE);
	
}

//===============================================================
// 函 数 名:get_next_position
// 功能描述:把l_firstpos和l_secondpos分别从指向当前字段的初始和终止处
//           移到下一个字段的初始和终止处
// 输入参数:string data,int*l_firstpos,int*l_secondpos
// 输出参数:void
// 创建日期:04-7-18
// 修改日期:
// 作    者:郑富强
// 附加说明:
//===============================================================
void get_next_position(string data,int*l_firstpos,int*l_secondpos)
{
    //让l_firstpos定位到下一个字段的起始处
	*l_firstpos=data.find_first_not_of(" ",*l_secondpos);
	if(*l_firstpos==-1)
		*l_firstpos=data.find_first_not_of("\t",*l_secondpos);
    char l_ch=data.at(*l_firstpos);
	while(l_ch==' '||l_ch=='\t')
	{
		if(l_ch=='\t')
			*l_firstpos=data.find_first_not_of("\t",*l_firstpos);
		else
			*l_firstpos=data.find_first_not_of(" ",*l_firstpos);
		l_ch=data.at(*l_firstpos);
	}

	//让l_secondpos定位到下一个字段的终止处
	*l_secondpos=data.find_first_of(" ",*l_firstpos);
	int l_i=data.find_first_of("\t",*l_firstpos);
	if(*l_secondpos>l_i&&l_i>=0)
		*l_secondpos=l_i;

}

//===============================================================
// 函 数 名:IncreaseDataSum
// 功能描述:有新数据加入时, 修改计数器的值
// 输入参数:主机名: ip, 数据类型: type
// 输出参数:void
// 创建日期:04-7-18
// 修改日期:04-7-18
// 作    者:郑富强
// 附加说明:对 File, Mail, Net, Proc 类型数据有效
//===============================================================
void IncreaseDataSum( LPCTSTR ip, int type )
{
	extern CRITICAL_SECTION g_criActiveClientList;
	extern ActivClient theActiveClientList;

	EnterCriticalSection( &g_criActiveClientList );

	int i = theActiveClientList.IsOnLine( ip );
	if ( i >= 0 )
		theActiveClientList.m_nDataSum[i][type]++;

	LeaveCriticalSection( &g_criActiveClientList );
}

//===============================================================
// 函 数 名:IncreaseDataSum
// 功能描述:有新数据加入时, 修改计数器的值
// 输入参数:主机名: ip, CPU 使用率: type
// 输出参数:void
// 创建日期:04-7-18
// 修改日期:04-7-18
// 作    者:郑富强
// 附加说明:对 CPU 类型数据有效
//===============================================================
void UpdateCpuUsage( LPCTSTR ip, int usage )
{
	extern CRITICAL_SECTION g_criActiveClientList;
	extern ActivClient theActiveClientList;

	EnterCriticalSection( &g_criActiveClientList );

	int i = theActiveClientList.IsOnLine( ip );
	// cpu 值第十秒更新一次, 每三秒收到一个新的数据
	// 故在显示的时候显示的是三次的平均值
	if ( i >= 0 )
		theActiveClientList.m_nDataSum[i][0] += usage;

	LeaveCriticalSection( &g_criActiveClientList );
}






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -