📄 socketthreadmanager.cpp
字号:
/*
*
*
* Copyright (c) 2000 Barak Weichselbaum <barak@komodia.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* Contact info:
* Site: http://www.komodia.com
* Email: barak@komodia.com
*/
#include "stdafx.h"
#include "SocketThreadManager.h"
#include "AsyncSocket.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define CSocketThreadManager_Class "CSocketThreadManager"
//##ModelId=3B43E6F40106
CSocketThreadManager::CSocketThreadManager(int iThreadCount,HINSTANCE hInstance) : CSpoofBase(),
m_iThreadCount(iThreadCount),
m_hInstance(hInstance)
{
try
{
//Set the class name
SetName(CSocketThreadManager_Class);
//Set our memeber
m_pThreadData=NULL;
//Start spawning threads
SpawnThreads();
//Create the critical section
InitializeCriticalSection(&m_pCSection);
}
ERROR_HANDLER("CSocketThreadManager")
}
//##ModelId=3B43E6F40118
CSocketThreadManager::~CSocketThreadManager()
{
try
{
//Release the critical section
DeleteCriticalSection(&m_pCSection);
//Delete the thread data
if (m_pThreadData)
{
for (int iCounter=0;iCounter<=m_iThreadCount;++iCounter)
//Post a stop message
if (m_pThreadData[iCounter].hThreadHandle)
{
PostThreadMessage(m_pThreadData[iCounter].dwThreadID,WM_QUIT,0,0);
//Delete the window
DestroyWindow(m_pThreadData[iCounter].hWindowHandle);
}
//Delete the structure
delete [] m_pThreadData;
}
}
ERROR_HANDLER("~CSocketThreadManager")
}
//##ModelId=3B43E6F40137
void CSocketThreadManager::SpawnThreads()
{
try
{
//Start creating threads
//Allocate the thread structure
m_pThreadData=new ThreadData[m_iThreadCount];
//And initialize it
memset(m_pThreadData,0,sizeof(ThreadData)*m_iThreadCount);
//Wait for all threads
HANDLE* pHandle;
pHandle=new HANDLE[m_iThreadCount];
//Reset them
memset(pHandle,0,sizeof(HANDLE)*m_iThreadCount);
//Start spawning
for (int iCounter=0;iCounter<m_iThreadCount;++iCounter)
{
//Create an event
m_pThreadData[iCounter].hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
//Save it to our array
pHandle[iCounter]=m_pThreadData[iCounter].hEvent;
//Set our instance
m_pThreadData[iCounter].hInstance=m_hInstance;
//And create it
m_pThreadData[iCounter].hThreadHandle=CreateThread(NULL,
0,
SocketThread,
(LPVOID)(m_pThreadData+iCounter),
0,
&m_pThreadData[iCounter].dwThreadID);
//Check the thread has been created
if (!m_pThreadData[iCounter].hThreadHandle)
{
//Report the error
ReportError("SpawnThreads","Failed to create thread!");
//Delete the handle array
delete [] pHandle;
//Quit
return;
}
}
//Wait for all the handles to finish
if (WaitForMultipleObjectsEx(m_iThreadCount,pHandle,TRUE,10000,FALSE)==WAIT_TIMEOUT)
//Report the error
ReportError("SpawnThreads","Timeout waiting for threads!");
//Release all the events
for (iCounter=0;iCounter<m_iThreadCount;++iCounter)
CloseHandle(pHandle[iCounter]);
//Delete all the handles
delete [] pHandle;
}
ERROR_HANDLER("SpawnThreads")
}
//##ModelId=3B43E6F4012C
DWORD WINAPI CSocketThreadManager::SocketThread(LPVOID lpParameter)
{
try
{
//Get the address of our data
ThreadData* pData;
pData=(ThreadData*)lpParameter;
//Create the window
pData->hWindowHandle=CreateWindowEx(0,CAsyncSocket_Class,SOCKET_WINDOW_NAME,
WS_OVERLAPPED,0,0,0,0,0,NULL,pData->hInstance,NULL);
//Alert we are done
SetEvent(pData->hEvent);
//Check we have this window
if (pData->hWindowHandle)
{
//Run a message map
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
//Translate and dispatch
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return FALSE;
}
ERROR_HANDLER_STATIC_RETURN(CSocketThreadManager_Class,"SocketThread",TRUE)
}
//##ModelId=3B43E6F40123
int CSocketThreadManager::GetMostAvailableThread()
{
try
{
int iIndex;
iIndex=0;
//Start searching the threads
for (int iCounter=1;iCounter<m_iThreadCount;++iCounter)
//Check is it larger
if (m_pThreadData[iCounter].iSocketCount<m_pThreadData[iIndex].iSocketCount && m_pThreadData[iCounter].hThreadHandle)
//Set the new index
iIndex=iCounter;
//Return the value
return iIndex+1;
}
ERROR_HANDLER_RETURN("GetMostAvailableThread",0)
}
//##ModelId=3B43E6F40105
HWND CSocketThreadManager::GetWindowHandle()
{
try
{
//Shared resource
EnterCriticalSection(&m_pCSection);
//Get the freeiest index
int iIndex;
iIndex=GetMostAvailableThread();
//Check it's valid
if (!iIndex)
{
//Leave the critical section
LeaveCriticalSection(&m_pCSection);
//Quit
return 0;
}
//Increase the socket count
++m_pThreadData[iIndex-1].iSocketCount;
//Leave the critical section
LeaveCriticalSection(&m_pCSection);
return m_pThreadData[iIndex-1].hWindowHandle;
}
ERROR_HANDLER("GetWindowHandle")
//Quit from the critical section
LeaveCriticalSection(&m_pCSection);
return 0;
}
//##ModelId=3B43E6F400FB
void CSocketThreadManager::DecreaseSocketCount(HWND hWindowHandle)
{
try
{
//First find the window handle
int iIndex;
iIndex=GetIndexByHWND(hWindowHandle);
//Check it's valid
if (!iIndex)
return;
//Enter the critical section
EnterCriticalSection(&m_pCSection);
//Decrement the socket count
if (m_pThreadData[iIndex-1].iSocketCount>0)
--m_pThreadData[iIndex-1].iSocketCount;
//Leave the critical section
LeaveCriticalSection(&m_pCSection);
return;
}
ERROR_HANDLER("DecreaseSocketCount")
//Error, release the critical section
LeaveCriticalSection(&m_pCSection);
}
//##ModelId=3B43E6F4011A
int CSocketThreadManager::GetIndexByHWND(HWND hHandle)
{
try
{
for (int iCounter=0;iCounter<m_iThreadCount;++iCounter)
if (m_pThreadData[iCounter].hWindowHandle==hHandle)
//Return it
return iCounter+1;
//Nothing
return 0;
}
ERROR_HANDLER_RETURN("GetIndexByHWND",0)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -