📄 rawsocketserverworker.cpp
字号:
/////////////////////////////////////////////////////////////////////
// Class Creator Version 2.0.000 Copyrigth (C) Zhang Zhanjun
///////////////////////////////////////////////////////////////////
// Implementation File RawSocketServerWorker.cpp
// class CWizRawSocketServerWorker
//
// 11/10/2004
///////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RawSocketServerWorker.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
// Events to interrupt blocking socket functions.
//__declspec( thread ) static const int HOOK_CANCEL_EVENTS = 2;
//__declspec( thread ) static HANDLE sh_HookCanselEvents[HOOK_CANCEL_EVENTS] = { NULL, NULL };
//__declspec( thread ) static int nHookEventsInstalled = 0;
//2004-10-16 modify for COM
#define HOOK_CANCEL_EVENTS 2
HANDLE sh_HookCanselEvents[MAXCLIENT+1][HOOK_CANCEL_EVENTS];
int nHookEventsInstalled[MAXCLIENT+1];
inline void ThrowIfNull(void* p)
{
if (p == NULL)
AfxThrowMemoryException();
}
// Function called from Windows Sockets blocking hook function
inline BOOL TestCancelEvents (int index, DWORD TimeOut = 0)
{
#ifdef _DEBUG
ASSERT(nHookEventsInstalled[index] <= HOOK_CANCEL_EVENTS);
for(INDEX i = 0; i < nHookEventsInstalled[index]; i++)
ASSERT(sh_HookCanselEvents[index][i] != NULL);
#endif
// Tests events - if one signaled, should cancel blocking function.
return (::WaitForMultipleObjects (nHookEventsInstalled[index], &sh_HookCanselEvents[index][0], FALSE, TimeOut) != WAIT_TIMEOUT);
}
// Windows Sockets blocking hook function
int BlockingHookIndex;
BOOL WINAPI BlockingHook()
{
// As simple as...
if (::TestCancelEvents(BlockingHookIndex, 0))
WSACancelBlockingCall();
return 0;
}
// Function installes blocking hook handler
inline BOOL SetHook(int index)
{
static BOOL bInstalled = FALSE;
// If not installed yet
if (!bInstalled)
{
// Try to install hook even if some
// blocking Windows Sockets operation is in progress.
BlockingHookIndex=index;
while (::WSASetBlockingHook(BlockingHook) == NULL)
{
if (::WSAGetLastError() != WSAEINPROGRESS)
{
return FALSE;
}
if(::TestCancelEvents(index, 100))
return FALSE;
}
bInstalled = TRUE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////
// class CWizRawSocketListener
///////////////////////////////////////////////////////////////////
// Default Constructor
CWizRawSocketListener::CWizRawSocketListener(int nPort)
: m_pListenSocket (NULL),
m_nPort (nPort)
{
for(int i=0; i<MAXCLIENT; i++)
{
clientSide[i]=NULL;
nHookEventsInstalled[i] = 0;
for(int j=0; j<HOOK_CANCEL_EVENTS; j++)
sh_HookCanselEvents[i][j] = NULL;
}
nHookEventsInstalled[i] = 0;
for(int j=0; j<HOOK_CANCEL_EVENTS; j++)
sh_HookCanselEvents[i][j] = NULL;
}
// Destructor
CWizRawSocketListener::~CWizRawSocketListener()
{
for(int i=0;i<MAXCLIENT;i++)
{
if(clientSide[i])
delete clientSide[i];
}
if (m_pListenSocket != NULL)
{
ASSERT(0);
delete m_pListenSocket;
}
}
// Method called from dispath thread.
void CWizRawSocketListener::Prepare ()
{
// Maybe install hook
if(!SetHook(MAXCLIENT))
throw CWizRawSocketListener::XCannotSetHook();
ASSERT(nHookEventsInstalled[MAXCLIENT] == 0);
// Create listening socket
if (m_pListenSocket != NULL)
{
ASSERT(0);
delete m_pListenSocket;
}
m_pListenSocket = new CWizSyncSocket (m_nPort);
ThrowIfNull (m_pListenSocket);
ASSERT(nHookEventsInstalled[MAXCLIENT] == 0);
#ifdef _DEBUG
TCHAR buff[100];
unsigned int nP;
VERIFY(m_pListenSocket->GetHostName (buff,100,nP));
TRACE(_T("Listening at %s:%d\n"), buff, nP);
#endif
}
// Method called from dispath thread.
void CWizRawSocketListener::CleanUp()
{
// close and destroy listening socket
delete m_pListenSocket;
m_pListenSocket = NULL;
}
struct EventInstall
{
EventInstall (int i, HANDLE h, int &n)
: m_n (n), index(i)
{
ASSERT(nHookEventsInstalled[index] <= m_n);
if (nHookEventsInstalled[index] > m_n)
throw CWizRawSocketListener::XCannotSetHookEvent();
sh_HookCanselEvents [index][m_n] = h;
nHookEventsInstalled[index] = m_n + 1;
n++;
}
~EventInstall ()
{
ASSERT(nHookEventsInstalled[index] == m_n + 1);
sh_HookCanselEvents [index][m_n] = NULL;
nHookEventsInstalled[index] = m_n;
}
int m_n;
int index;
};
// Method called from dispath thread.
BOOL CWizRawSocketListener::WaitForData(int& index, HANDLE hShutDownEvent)
{
//TRACE(_T("Wait for data thread %d\n"),AfxGetThread()->m_hThread);
m_hAcceptedSocket = INVALID_SOCKET;
// Install shutdown event.
int n = 0;
EventInstall ei (MAXCLIENT, hShutDownEvent, n);
// Maybe set hook.
if(!SetHook(MAXCLIENT))
throw CWizRawSocketListener::XCannotSetHook();
BOOL idleSocket=TRUE;
while(1)
{
if (::WaitForSingleObject(hShutDownEvent,0) != WAIT_TIMEOUT)
{
return FALSE;
}
for(index=0; index<MaxClient; index++)
if(clientSide[index]==NULL)
break;
if(index<MaxClient) //found
break;
Sleep(100);
}
TRACE(_T("Accept %d\n"),index);
// Accept pending connections or wait.
while (1)
{
// Get accepted socket.
SOCKET h = m_pListenSocket->Accept();//Blocking untill connect from Client
// Shutdown?
if (::WaitForSingleObject(hShutDownEvent,0) != WAIT_TIMEOUT)
return FALSE;
// If it's connected client, go to serve it.
if (h != INVALID_SOCKET)
{
m_hAcceptedSocket = h;
clientSide[index]=new CWizReadWriteSocket(m_hAcceptedSocket);
return TRUE;
}
else
return FALSE;
}
return TRUE;
}
// Method called from dispath thread.
BOOL CWizRawSocketListener::TreatData(int index,HANDLE hShutDownEvent, HANDLE hDataTakenEvent)
{
// TRACE(_T("Treat data thread %d\n"),AfxGetThread()->m_hThread);
int n = 0;
// Install shutdown event.
EventInstall ei (index, hShutDownEvent,n);
// Create client side socket to communicate with client.
// Signal dispather to continue waiting.
::SetEvent(hDataTakenEvent);
// Maybe set hook.
if(!SetHook(index))
throw CWizRawSocketListener::XCannotSetHook();
#ifdef _DEBUG
TCHAR buff[100];
unsigned int nP = 0;
clientSide[index]->GetPeerName (buff,100,nP);
TRACE(_T("Connected to %s:%d\n"), buff, nP);
#endif
while(1)
{
// Shutdown?
if (::WaitForSingleObject(hShutDownEvent, 0) == WAIT_OBJECT_0)
return FALSE;
// Exchange with client.
if (!ReadWrite(index,*clientSide[index]))//Read data
{
if(clientSide[index])
{
delete clientSide[index];
clientSide[index]=NULL;
}
break;
}
}
return TRUE;
}
//Release socket handle
void CWizRawSocketListener::Close(int index)
{
if(clientSide[index])
{
delete clientSide[index];
clientSide[index]=NULL;
}
}
//Close socket
void CWizRawSocketListener::ShutDown(int index)
{
if(clientSide[index])
{
clientSide[index]->Close();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -