Wince Socket Server

/********************************************************************
 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();
}
//===========================================================================

你可能感兴趣的:(exception,socket,server,null,delete,WinCE)