📄 multhreadsever.cpp
字号:
// 功能描述:监听是否有客户连接,若有则创建相应子线程去服务它
// 输入参数: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 + -