回调函数实例

class CAsyncSocketExHelperWindow
{
public:
CAsyncSocketExHelperWindow()
{
//Initialize data
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
m_nWindowDataSize = 512;
m_nSocketCount = 0;
m_nWindowDataPos = 0;

//Create window
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandle(0);
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = _T("CAsyncSocketEx Helper Window");
wndclass.hIconSm = 0;
RegisterClassEx(&wndclass);

m_hWnd = CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
ASSERT( m_hWnd );
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
};

virtual ~CAsyncSocketExHelperWindow()
{
//Clean up socket storage
delete[] m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = 0;
m_nWindowDataSize = 0;
m_nSocketCount = 0;

//Destroy window
if (m_hWnd)
{
DestroyWindow(m_hWnd);
m_hWnd = 0;
}
}

//Adds a socket to the list of attached sockets
BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
ASSERT( pSocket );
if (!m_nWindowDataSize)
{
ASSERT( !m_nSocketCount );
m_nWindowDataSize = 512;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
memset(m_pAsyncSocketExWindowData, 0, 512 * sizeof(t_AsyncSocketExWindowData));
}

if (nSocketIndex != -1)
{
ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize>nSocketIndex );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
ASSERT( m_nSocketCount );
return TRUE;
}

//Increase socket storage if too small
if (m_nSocketCount >= m_nWindowDataSize - 10)
{
int nOldWindowDataSize = m_nWindowDataSize;
ASSERT( m_nWindowDataSize < MAX_SOCKETS );
m_nWindowDataSize += 512;
if (m_nWindowDataSize > MAX_SOCKETS)
m_nWindowDataSize = MAX_SOCKETS;

t_AsyncSocketExWindowData* tmp = m_pAsyncSocketExWindowData;
m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
memset(m_pAsyncSocketExWindowData + nOldWindowDataSize, 0, (m_nWindowDataSize - nOldWindowDataSize) * sizeof(t_AsyncSocketExWindowData));
delete[] tmp;
}

//Search for free slot
for (int i = m_nWindowDataPos; i < m_nWindowDataSize + m_nWindowDataPos; i++)
{
if (m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket == NULL)
{
m_pAsyncSocketExWindowData[i % m_nWindowDataSize].m_pSocket = pSocket;
nSocketIndex = i % m_nWindowDataSize;
m_nWindowDataPos = (i + 1) % m_nWindowDataSize;
m_nSocketCount++;
return TRUE;
}
}

//No slot found, maybe there are too much sockets!
return FALSE;
}

//Removes a socket from the socket storage
BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
{
UNREFERENCED_PARAMETER(pSocket);
ASSERT( pSocket );

if (nSocketIndex == -1)
return TRUE;

ASSERT( m_pAsyncSocketExWindowData );
ASSERT( m_nWindowDataSize > 0 );
ASSERT( m_nSocketCount > 0 );
ASSERT( m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket );
m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket = 0;
nSocketIndex = -1;
m_nSocketCount--;

return TRUE;
}

//Processes event notifications sent by the sockets or the layers
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
try
{
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
if (message >= WM_SOCKETEX_NOTIFY)
{
//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );

if (message < (UINT)(WM_SOCKETEX_NOTIFY + pWnd->m_nWindowDataSize)) //Index is within socket storage
{
//Lookup socket and verify if it's valid
CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[message - WM_SOCKETEX_NOTIFY].m_pSocket;
SOCKET hSocket = wParam;
if (!pSocket)
return 0;
if (hSocket == INVALID_SOCKET)
return 0;
if (pSocket->m_SocketData.hSocket != hSocket)
return 0;

int nEvent = lParam & 0xFFFF;
int nErrorCode = lParam >> 16;

//Dispatch notification
#ifndef NOLAYERS
if (!pSocket->m_pFirstLayer)
{
#endif //NOLAYERS
//Dispatch to CAsyncSocketEx instance
switch (nEvent)
{
case FD_READ:
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->OnReceive(nErrorCode);
break;
}
case FD_FORCEREAD: //Forceread does not check if there's data waiting
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
pSocket->OnClose(nErrorCode);
break;
}
}
#ifndef NOLAYERS
else //Dispatch notification to the lowest layer
{
if (nEvent == FD_READ)
{
DWORD nBytes;
if (!pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
else
pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
}
}
#endif //NOLAYERS
return 0;
}
#ifndef NOLAYERS
else if (message == WM_SOCKETEX_TRIGGER) //Notification event sent by a layer
{
//Verify parameters, lookup socket and notification message
if (!wParam)
return 0;
CAsyncSocketEx *pSocket = (CAsyncSocketEx *)wParam;
CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = (CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
if (pSocket->m_SocketData.hSocket == INVALID_SOCKET) {
delete pMsg;
return 0;
}

int nEvent = pMsg->lEvent & 0xFFFF;
int nErrorCode = pMsg->lEvent >> 16;

//Dispatch to layer
if (pMsg->pLayer)
pMsg->pLayer->CallEvent(nEvent, nErrorCode);
else
{
//Dispatch to socket class
switch (nEvent)
{
case FD_READ:
if (pSocket->m_lEvent & FD_READ)
pSocket->OnReceive(nErrorCode);
break;
case FD_FORCEREAD:
if (pSocket->m_lEvent & FD_FORCEREAD)
pSocket->OnReceive(nErrorCode);
break;
case FD_WRITE:
if (pSocket->m_lEvent & FD_WRITE)
pSocket->OnSend(nErrorCode);
break;
case FD_CONNECT:
if (pSocket->m_lEvent & FD_CONNECT)
pSocket->OnConnect(nErrorCode);
break;
case FD_ACCEPT:
if (pSocket->m_lEvent & FD_ACCEPT)
pSocket->OnAccept(nErrorCode);
break;
case FD_CLOSE:
if (pSocket->m_lEvent & FD_CLOSE)
pSocket->OnClose(nErrorCode);
break;
}
}
delete pMsg;
return 0;
}
#endif //NOLAYERS
else if (message == WM_SOCKETEX_GETHOST)
{
//WSAAsyncGetHostByName reply

//Verify parameters
ASSERT( hWnd );
CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLong(hWnd, GWL_USERDATA);
ASSERT( pWnd );

CAsyncSocketEx *pSocket = NULL;
int i;
for (i = 0; i < pWnd->m_nWindowDataSize; i++)
{
pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
break;
}
if (i == pWnd->m_nWindowDataSize)
return 0;

int nErrorCode = lParam >> 16;
if (nErrorCode) {
pSocket->OnConnect(nErrorCode);
return 0;
}

SOCKADDR_IN sockAddr = {0};
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
sockAddr.sin_port = htons((u_short)pSocket->m_nAsyncGetHostByNamePort);

if (!pSocket->OnHostNameResolved(&sockAddr))
{
return 0;
}

BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
delete[] pSocket->m_pAsyncGetHostByNameBuffer;
pSocket->m_pAsyncGetHostByNameBuffer = 0;
pSocket->m_hAsyncGetHostByNameHandle = 0;

if (!res && GetLastError() != WSAEWOULDBLOCK)
pSocket->OnConnect(GetLastError());

return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
#if !NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
catch(CException* e){
TCHAR szError[1024];
e->GetErrorMessage(szError, ARRSIZE(szError));
const CRuntimeClass* pRuntimeClass = e->GetRuntimeClass();
LPCSTR pszClassName = (pRuntimeClass) ? pRuntimeClass->m_lpszClassName : NULL;
if (!pszClassName)
pszClassName = "CException";
TRACE(_T("*** Unknown %hs exception in CAsyncSocketExHelperWindow::WindowProc - %s\n"), pszClassName, szError);
e->Delete();
}
catch (...) {
// TODO: This exception handler should definitively *not* be here. Though we seem to need it to
// catch some very strange crashs which deal with socket deletion problems in the client's TCP socket.
TRACE("*** Unknown exception in CAsyncSocketExHelperWindow::WindowProc\n");
ASSERT(0);
}
return 0;
#endif//!NO_USE_CLIENT_TCP_CATCH_ALL_HANDLER
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值