Server is use WSAAsyncSelect TCP mode .
Here is the part of code:
BOOL CServerDlg::InitSocket()
{
WSADATA wsaData;
int iErrorCode;
if(WSAStartup(MAKEWORD(2,2),&wsaData))
{
CString strError;
strError.Format(_T("WSAStartup failed: %d"),GetLastError());
AddSEHLog(strError);
WSACleanup();
return FALSE;
}
m_socket=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,0);
if(m_socket==INVALID_SOCKET)
{
CString strError;
strError.Format(_T("WSASocket failed: %d"),GetLastError());
AddSEHLog(strError);
WSACleanup();
return FALSE;
}
SOCKADDR_IN sockServerAddr;
DWORD dwPort = GetListenPort();
sockServerAddr.sin_family =AF_INET;
sockServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
sockServerAddr.sin_port= htons(dwPort);
if(bind(m_socket,(LPSOCKADDR)&sockServerAddr,sizeof(sockServerAddr)) == SOCKET_ERROR)
{
CString strError;
strError.Format(_T("bind failed: %d"),GetLastError());
AddSEHLog(strError);
closesocket(m_socket);
WSACleanup();
return FALSE;
}
if(listen(m_socket,64) == SOCKET_ERROR)
{
CString strError;
strError.Format(_T("list failed: %d"),GetLastError());
AddSEHLog(strError);
return FALSE;
}
iErrorCode = WSAAsyncSelect(m_socket,m_hWnd,WM_SERVER_ACCEPT,FD_ACCEPT);
if(iErrorCode == SOCKET_ERROR)
{
CString strError;
strError.Format(_T("WSAAsyncSelect failed: %d"),GetLastError());
AddSEHLog(strError);
return FALSE;
}
AddSEHLog(_T("server start success !"));
return TRUE;
}
LRESULT CServerDlg::OnAccept(WPARAM wParam, LPARAM lParam)
{
if(WSAGETSELECTERROR(wParam))
{
DeleteClient(wParam);
ReFreshClient();
return 0L;
}
if(WSAGETSELECTEVENT(lParam) == FD_ACCEPT)
{
SOCKADDR_IN m_sockClientAddr;
int nCount = 100;
int len=sizeof(m_sockClientAddr);
CString strIP = _T("");
CString strPort = _T("");
int nLen;
HANDLE hThread = INVALID_HANDLE_VALUE;
SOCKET Client = accept(m_socket,(LPSOCKADDR)&m_sockClientAddr,&nCount);
RECVPARAM recvParam;
recvParam.m_sock = Client;
recvParam.m_hWnd = m_hWnd;
m_cArrayList.Add(recvParam);
hThread = CreateThread(NULL,0,RecvProc,(LPVOID)&recvParam,CREATE_SUSPENDED,NULL);
SetThreadPriority(hThread,THREAD_PRIORITY_NORMAL);
ResumeThread(hThread);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
ReFreshClient();
}
return 0L;
}
LRESULT CServerDlg::OnReadClose(WPARAM wParam, LPARAM lParam)
{
if(WSAGETSELECTERROR(lParam))
{
DeleteClient(sockClient);
ReFreshClient();
return -1;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
{
RECVPARAM *pRecvParam = new RECVPARAM;
pRecvParam->m_sock = sockClient;
pRecvParam->m_hWnd = m_hWnd;
pRecvParam->m_pMainDlg = this;
HANDLE hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadThreadProc,pRecvParam,CREATE_SUSPENDED,NULL);
SetThreadPriority(hThread,THREAD_PRIORITY_NORMAL);
ResumeThread(hThread);
Sleep(100);
CloseHandle(hThread);
}
break;
case FD_CLOSE:
{
DeleteClient(sockClient);
ReFreshClient();
}
break;
}
return 0L;
}
DWORD CServerDlg::ReadThreadProc(LPVOID pParam)
{
RECVPARAM *pRecvParam = (RECVPARAM *)pParam;
SOCKET sock = pRecvParam->m_sock;
HWND hwnd = pRecvParam->m_hWnd;
CServerDlg *pDlg = (CServerDlg *)((RECVPARAM*)pParam)->m_pMainDlg;
if(MyWSARecvFrom(sock,&wsabufRecv,1,&dwRead,&dwFlag,(SOCKADDR*)&addrFrom,&len,NULL,NULL)== SOCKET_ERROR)
{
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)wsabufRecv.buf);
delete[] wsabufRecv.buf;
delete pRecvParam;
return -1;
}
::PostMessage(hwnd,WM_RECVDATA,(WPARAM)sock,(LPARAM)wsabufRecv.buf);
pszRecv = clientCMD.PaserData(sock,wsabufRecv.buf);
delete pRecvParam;
delete [] wsabufRecv.buf;
wsabufRecv.buf = NULL;
return 0;
}
Here is a bug:
If many client(about 10/sec) connect the server when in the same time
the server's window cannot response anymore, and it will can't response the normal clients request.
I think this like WEB DDOS Attack. I worry about this bug for a long time.
Is this have to changed into IOCP mode ?
Is there any idea ?