/********************************************************************
created: 2011/02/24
created: 24:2:2011 17:52
filename: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600/Socket/SK_Server.h
file path: g:/20110221文件整理/源码/小工具_实现代码(20110221版)/CE600/Socket
file base: SK_Server
file ext: h
author: Clark
purpose:
*********************************************************************/
#pragma once
#include <Winsock2.h>
#include "../CE600.h"
//typedef void(__cdecl* SK_SERVER_AFTER_RECV)(char strIP[256],char strContext[1024], LPVOID pOwner);
//typedef void(__cdecl* SK_SERVER_AFTER_SEND)(char strIP[256],char strContext[1024], LPVOID pOwner);
typedef void(__stdcall* SK_SERVER_AFTER_RECV)(char strIP[256],char strContext[1024], LPVOID pOwner);
typedef void(__stdcall* SK_SERVER_AFTER_SEND)(char strIP[256],char strContext[1024], LPVOID pOwner);
class ServerHead;
class ServerBody;
class SK_Server
{
public:
SK_Server(LPVOID pRecvOwner, SK_SERVER_AFTER_RECV AfterRecv,
LPVOID pSendOwner,SK_SERVER_AFTER_SEND AfterSend,
char* IP = "0.0.0.0",
DWORD dwPort = 4700);
virtual ~SK_Server(void);
void Send(int iID, char strContext[1024]);
SOCKADDR_IN GetIP();
private:
LPVOID m_pRecvOwner;
LPVOID m_pSendOwner;
SK_SERVER_AFTER_RECV m_OnAfterRecv;
SK_SERVER_AFTER_SEND m_OnAfterSend;
enum SK_PAR
{
SERVER_CLIENT_SIZE = 2
};
ServerHead *m_pSrvHead;
ServerBody *m_pSrvBody[SERVER_CLIENT_SIZE];
friend class ServerHead;
friend class ServerBody;
};
////////////////////////////////////////////
#include "StdAfx.h"
#include "SK_Server.h"
#include <vector>
#include <tchar.h>
#include <fstream>
//#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Ws2.lib")
using namespace std;
//---------------------------------------------------------------------
class ServerHead
{
public:
ServerHead(SK_Server* pServer, char* IP, DWORD dwPort, DWORD dwSize);
~ServerHead();
void Run();
SOCKADDR_IN GetIP(){ return m_addrSrv; }
const DWORD SERVER_PORT;
private:
static DWORD WINAPI AcceptThread(LPVOID lparam);
void SetPort(char* IP, DWORD dwPort, DWORD dwSize);
ThreadEx* m_pServerThread;
HANDLE m_hServerCloseEvent;
SOCKET m_sockSrv;
SK_Server* m_pServer;
SOCKADDR_IN m_addrSrv;
};
class ServerBody
{
public:
ServerBody();
~ServerBody();
void Init();
void Work(SOCKET sockClient, SOCKADDR_IN addrClient, LPVOID pPar);
bool IsNull();
void DoEvent(SK_Server* pSK_Server);
void Send(SK_Server* pSK_Server,char strContext[1024]);
private:
static DWORD WINAPI WorkThread(LPVOID lparam);
ThreadEx* m_pClientThread;
HANDLE m_hClientCloseEvent;
SOCKET m_sockClient;
SOCKADDR_IN m_skaddrClient;
HANDLE m_hMutex;
};
struct CONTROL_NODE
{
SK_Server* pServer;
int iID;
};
DWORD ServerHead::AcceptThread(LPVOID lparam)
{
SK_Server* pSockerServer = (SK_Server*)lparam;
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while( TRUE)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(pSockerServer->m_pSrvHead->m_hServerCloseEvent,200))
{
break;
}
//服务器需不断的等待客户端请求的到来
SOCKET sockClient = accept(pSockerServer->m_pSrvHead->m_sockSrv,(SOCKADDR*)&addrClient,&len);
for(int i=0; i<pSockerServer->SERVER_CLIENT_SIZE; i++)
{
if( pSockerServer->m_pSrvBody[i]->IsNull())
{
CONTROL_NODE* pCONTROL_NODE = new CONTROL_NODE();
pCONTROL_NODE->pServer = pSockerServer;
pCONTROL_NODE->iID = i;
pSockerServer->m_pSrvBody[i]->Work(sockClient,addrClient,pCONTROL_NODE);
break;
}
}
}
return 0;
}
DWORD ServerBody::WorkThread(LPVOID lparam)
{
CONTROL_NODE* pCONTROL_NODE = (CONTROL_NODE*)lparam;
if( NULL != pCONTROL_NODE)
{
SK_Server* pSockerServer = pCONTROL_NODE->pServer;
int iID = pCONTROL_NODE->iID;
delete pCONTROL_NODE;
pCONTROL_NODE = NULL;
pSockerServer->m_pSrvBody[iID]->DoEvent(pSockerServer);
pSockerServer->m_pSrvBody[iID]->Init();
}
return 0;
}
//===========================================================================
//---------------------------------------------------------------------
ServerHead::ServerHead(SK_Server* pServer, char* IP, DWORD dwPort, DWORD dwSize):
SERVER_PORT(dwPort)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
throw &std::exception("Failed to WinceXmlEx!");
}
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();
throw &std::exception("Failed to WinceXmlEx!");
}
SetPort(IP,SERVER_PORT,pServer->SERVER_CLIENT_SIZE);
m_pServerThread = NULL;
m_pServer = pServer;
}
void ServerHead::Run()
{
if( NULL != m_pServerThread)
delete m_pServerThread;
m_pServerThread = new ThreadEx(m_hServerCloseEvent,AcceptThread,m_pServer);
}
ServerHead::~ServerHead()
{
if( NULL != m_pServerThread)
delete m_pServerThread;
m_pServerThread = NULL;
WSACleanup();
}
void ServerHead::SetPort( char* IP,DWORD dwPort, DWORD dwSize)
{
m_sockSrv = socket(AF_INET,SOCK_STREAM,0);//创建套接字
//m_addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
m_addrSrv.sin_addr.S_un.S_addr=inet_addr(IP);
m_addrSrv.sin_family=AF_INET;
m_addrSrv.sin_port=htons(dwPort);//端口号选择需在1024以上的
bind(m_sockSrv,(SOCKADDR*)&m_addrSrv,sizeof(SOCKADDR));//bind 绑定到本地地址和端口上
listen(m_sockSrv,dwSize);//listen将套接字设置为监听模式,客户端最大链接数
}
//===========================================================================
//---------------------------------------------------------------------
ServerBody::ServerBody()
{
m_pClientThread = NULL;
m_hClientCloseEvent = NULL;
m_sockClient = NULL;
TCHAR szTemp[MAX_PATH];
_stprintf(szTemp,_T("MUTEX_FOR_CLIENT_NODE_%x"),this);
m_hMutex = CreateMutex(NULL,FALSE,szTemp);
Init();
}
ServerBody::~ServerBody()
{
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,5000))
{
ReleaseMutex(m_hMutex);
}
if( NULL != m_pClientThread)
delete m_pClientThread;
m_pClientThread = NULL;
m_hClientCloseEvent = NULL;
m_sockClient = NULL;
CloseHandle(m_hMutex);
}
void ServerBody::Init()
{
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
m_pClientThread = NULL;
m_hClientCloseEvent = NULL;
m_sockClient = NULL;
ReleaseMutex(m_hMutex);
}
}
void ServerBody::Work(SOCKET sockClient, SOCKADDR_IN addrClient, LPVOID pPar)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex,INFINITE))
{
if( NULL == m_pClientThread)
{
m_sockClient = sockClient;
m_skaddrClient = addrClient;
m_pClientThread = new ThreadEx(m_hClientCloseEvent,WorkThread,pPar);
}
ReleaseMutex(m_hMutex);
}
}
bool ServerBody::IsNull()
{
if( NULL != m_pClientThread)
return false;
return true;
}
void ServerBody::DoEvent(SK_Server* pSK_Server)
{
WSAEVENT ev = WSACreateEvent();
int ret = WSAEventSelect(m_sockClient, ev, FD_READ|FD_CLOSE);
const int BUF_SIZE = 1024;
while( TRUE)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(ev,200))
{
WSANETWORKEVENTS evInfo;
memset(&evInfo, 0,sizeof(evInfo));
ret = WSAEnumNetworkEvents(m_sockClient,ev,&evInfo);
if(evInfo.lNetworkEvents & FD_READ)
{//只要接收区始终有数据存在(不用recv取出),该事件就始终保持触发态
char strID[256];
sprintf(strID,"FD_READ|%s(addr):%d(port):%d(sock)", inet_ntoa(m_skaddrClient.sin_addr),
pSK_Server->m_pSrvHead->SERVER_PORT,m_sockClient);
char recvBuf[BUF_SIZE];
int iLen = 0;
memset(recvBuf,0,BUF_SIZE);
iLen = recv(m_sockClient,recvBuf,BUF_SIZE-1,0); //接收客户端数据(必须BUF_SIZE-1以给/0留下空间)
if( iLen > 0)
{
recvBuf[iLen] = '/0';
pSK_Server->m_OnAfterRecv(strID, recvBuf, pSK_Server->m_pRecvOwner);
}
}
else if(evInfo.lNetworkEvents & FD_CLOSE)
{
char strID[256];
sprintf(strID,"FD_CLOSE|%s(addr):%d(port):%d(sock)", inet_ntoa(m_skaddrClient.sin_addr),
pSK_Server->m_pSrvHead->SERVER_PORT,m_sockClient);
pSK_Server->m_OnAfterRecv(strID, "Close", pSK_Server->m_pRecvOwner);
break;
}
}
}
closesocket(m_sockClient);
}
void ServerBody::Send(SK_Server* pSK_Server,char strContext[1024])
{
char strID[256];
sprintf(strID,"%s(addr):%d(port):%d(sock)", inet_ntoa(m_skaddrClient.sin_addr),
pSK_Server->m_pSrvHead->SERVER_PORT,m_sockClient);
send(m_sockClient,strContext,strlen(strContext)+1,0); //向客户端发送数据
pSK_Server->m_OnAfterSend(strID, strContext, pSK_Server->m_pSendOwner);
}
//===========================================================================
//---------------------------------------------------------------------
SK_Server::SK_Server(LPVOID pRecvOwner, SK_SERVER_AFTER_RECV AfterRecv,
LPVOID pSendOwner,SK_SERVER_AFTER_SEND AfterSend,
char* IP,
DWORD dwPort):
m_pRecvOwner(NULL),
m_pSendOwner(NULL),
m_OnAfterRecv(NULL),
m_OnAfterSend(NULL),
m_pSrvHead(NULL)
{
m_pRecvOwner = pRecvOwner;
m_pSendOwner = pSendOwner;
m_OnAfterRecv = AfterRecv;
m_OnAfterSend = AfterSend;
for(int i=0; i<SERVER_CLIENT_SIZE; i++)
m_pSrvBody[i] = new ServerBody();
try
{
m_pSrvHead = new ServerHead(this,IP,dwPort,SERVER_CLIENT_SIZE);
}
catch (std::exception* e)
{
throw e;
}
m_pSrvHead->Run();
}
SK_Server::~SK_Server(void)
{
if( NULL != m_pSrvHead)
delete m_pSrvHead;
m_pSrvHead = NULL;
for(int i=0; i<SERVER_CLIENT_SIZE; i++)
{
if( NULL != m_pSrvBody[i])
delete m_pSrvBody[i];
m_pSrvBody[i] = NULL;
}
}
void SK_Server::Send( int iID, char strContext[1024] )
{
if( iID < 0 || iID>=SERVER_CLIENT_SIZE)
{
for(int i=0; i<SERVER_CLIENT_SIZE; i++)
{
if( !m_pSrvBody[i]->IsNull())
{
m_pSrvBody[i]->Send(this,strContext);
}
}
}
else
{
m_pSrvBody[iID]->Send(this,strContext);
}
}
SOCKADDR_IN SK_Server::GetIP()
{
return m_pSrvHead->GetIP();
}
//===========================================================================