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

📄 rawsocketserverworker.cpp

📁 pocket pc 2003系统下的数据通讯和文件传输
💻 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 + -