123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- #include "StdAfx.h"
- #include "IServerImpl.h"
- #include <comdef.h>
- #include <atlbase.h>
- #include <strsafe.h>
- #include "ThreadPool.hpp"
- #include "ClientProcess.h"
- // #ifdef _DEBUG
- // #define new DEBUG_NEW
- // #endif
- const int AF_IPV4 = 0;
- const int AF_IPV6 = 1;
- const int SOCK_TCP = SOCK_STREAM-1;
- const int SOCK_UDP = SOCK_DGRAM-1;
- namespace ServerSocketImpl
- {
- IServerImpl* g_pServerSocket[20] = {0};
- IServerImpl::IServerImpl():m_nMode(AF_IPV4)
- ,m_nSockType(SOCK_TCP)
- ,m_strPort(_T("64320"))
- ,m_nSocketIndex(0)
- {
- m_bStopbeat = FALSE;
- m_hRunObject = NULL;
- m_hClearInvalidateSocketThread = NULL;
- InitializeCriticalSection( &m_csProcessData );
- m_SocketServer.SetInterface(this);
- }
- IServerImpl::~IServerImpl()
- {
- m_SocketServer.Terminate();
- DeleteCriticalSection( &m_csProcessData );
- }
- BOOL IServerImpl::Initialize()
- {
- TCHAR szIPAddr[MAX_PATH] = { 0 };
- CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET);
- //AppendText(_T("Local Address (IPv4): %s\r\n"), szIPAddr);
- CSocketHandle::GetLocalAddress(szIPAddr, MAX_PATH, AF_INET6);
- //AppendText(_T("Local Address (IPv6): %s\r\n"), szIPAddr);
- return TRUE;
- }
- void IServerImpl::Start(IN LPCTSTR strPort,IN const int &nMode)
- {
- m_nMode = nMode;
- int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
- if (!m_SocketServer.StartServer(NULL, strPort, nFamily, (m_nSockType+1)))
- {
- //OutputDebugString(_T("\n连接服务器失败!\n"));
- AfxMessageBox(_T("Failed to start server."), NULL, MB_ICONSTOP);
- return;
- }
-
- CClientProcess::GetInstance()->StartMsgWork();
- //SyncControls();
- }
- void IServerImpl::Stop()
- {
- if(m_hRunObject)
- SetEvent(m_hRunObject);
- if( m_hClearInvalidateSocketThread )
- {
- if (WaitForSingleObject(m_hClearInvalidateSocketThread,INFINITE) != WAIT_FAILED)
- {
- CloseHandle(m_hClearInvalidateSocketThread);
- m_hClearInvalidateSocketThread = NULL;
- }
- }
- if ( m_hRunObject )
- CloseHandle( m_hRunObject );
- m_hRunObject = NULL;
- m_SocketServer.Terminate();
- //SyncControls();
- }
- void IServerImpl::Send()
- {
- if ( m_SocketServer.IsOpen() )
- {
- CString strMsg;
- //m_ctlMessage.GetWindowText( strMsg );
- if ( strMsg.IsEmpty() )
- {
- //AppendText( _T("Please enter the message to send.\r\n") );
- return;
- }
- USES_CONVERSION;
- if (m_nSockType == SOCK_TCP)
- {
- const LPBYTE lpbData = (const LPBYTE)(T2CA(strMsg));
- // unsafe access to Socket list!
- #ifdef SOCKHANDLE_USE_OVERLAPPED
- const SocketContextList& sl = m_SocketServer.GetSocketList();
- for(SocketContextList::const_iterator citer = sl.begin(); citer != sl.end(); ++citer)
- #else
- const SocketList& sl = m_SocketServer.GetSocketList();
- for(SocketList::const_iterator citer = sl.begin(); citer != sl.end(); ++citer)
- #endif
- {
- CSocketHandle sockHandle;
- sockHandle.Attach( (*citer) );
- sockHandle.Write(lpbData, strMsg.GetLength(), NULL);
- sockHandle.Detach();
- }
- }
- else
- {
- SockAddrIn servAddr, sockAddr;
- m_SocketServer->GetSockName(servAddr);
- GetDestination(sockAddr);
- if ( servAddr != sockAddr )
- {
- m_SocketServer.Write((const LPBYTE)(T2CA(strMsg)), strMsg.GetLength(), sockAddr);
- }
- else
- {
- //AppendText( _T("Please change the port number to send message to a client.\r\n") );
- }
- }
- }
- else
- {
- AfxMessageBox(_T("Socket is not connected"));
- }
- }
- void IServerImpl::SendAll(CSocketHandle &sockHandle, unsigned char *pMsg, int nLength)
- {
- if ( m_SocketServer.IsOpen() )
- {
- USES_CONVERSION;
- if (m_nSockType == SOCK_TCP)
- {
- // unsafe access to Socket list!
- const LPBYTE lpbData = (const LPBYTE)(pMsg);
- sockHandle.Write(lpbData, nLength, NULL);
- }
- else
- {
- SockAddrIn servAddr, sockAddr;
- m_SocketServer->GetSockName(servAddr);
- GetDestination(sockAddr);
- if ( servAddr != sockAddr )
- {
- m_SocketServer.Write((const LPBYTE)*pMsg, nLength, sockAddr);
- }
- else
- {
- }
- }
- }
- else
- {
- }
- }
- void IServerImpl::ToprocessRecivebuf(IN PerSocketContext &sockHandle, IN const BYTE* pReceivebuf, IN DWORD dwReceiveSize)
- {
-
- }
- int IServerImpl::OnIntegrityPacket(IN PerSocketContext &sockHandle, IN void *pIntegrityPacket)
- {
-
- return 0;
- }
- void IServerImpl::GetAddress(const SockAddrIn& addrIn, CString& rString) const
- {
- TCHAR szIPAddr[MAX_PATH] = { 0 };
- CSocketHandle::FormatIP(szIPAddr, MAX_PATH, addrIn);
- rString.Format(_T("%s : %d"), szIPAddr, static_cast<int>(static_cast<UINT>(ntohs(addrIn.GetPort()))) );
- }
- void IServerImpl::AppendText(LPCTSTR lpszFormat, ...)
- {
- // if ( !::IsWindow(m_ctlMsgList.GetSafeHwnd()) ) return;
- // TCHAR szBuffer[512];
- // HWND hWnd = m_ctlMsgList.GetSafeHwnd();
- // DWORD dwResult = 0;
- // if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, 0, SMTO_NORMAL, 500L, &dwResult) != 0)
- // {
- // int nLen = (int) dwResult;
- // if (SendMessageTimeout(hWnd, EM_SETSEL, nLen, nLen, SMTO_NORMAL, 500L, &dwResult) != 0)
- // {
- // size_t cb = 0;
- // va_list args;
- // va_start(args, lpszFormat);
- // ::StringCchVPrintfEx(szBuffer, 512, NULL, &cb, 0, lpszFormat, args);
- // va_end(args);
- // SendMessageTimeout(hWnd, EM_REPLACESEL, FALSE, reinterpret_cast<LPARAM>(szBuffer), SMTO_NORMAL, 500L, &dwResult);
- // }
- // }
- }
- bool IServerImpl::GetDestination(SockAddrIn& addrIn) const
- {
- CString strPort;
- //GetDlgItemText(IDC_SVR_PORT, strPort);
- int nFamily = (m_nMode == AF_IPV4) ? AF_INET : AF_INET6;
- return addrIn.CreateFrom(NULL, strPort, nFamily);
- }
- bool IServerImpl::SetupMCAST()
- {
- const TCHAR szIPv4MCAST[] = TEXT("239.121.1.2");
- const TCHAR szIPv6MCAST[] = TEXT("FF02:0:0:0:0:0:0:1"); // All Nodes local address
- bool result = false;
- if ( m_nSockType == SOCK_UDP )
- {
- if ( m_nMode == AF_IPV4 ) {
- result = m_SocketServer->AddMembership(szIPv4MCAST, NULL);
- } else {
- result = m_SocketServer->AddMembership(szIPv6MCAST, NULL);
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- hr = hr;
- }
- }
- return result;
- }
- ///////////////////////////////////////////////////////////////////////////////
- void IServerImpl::OnThreadBegin(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr;
- SockAddrIn sockAddr;
- m_SocketServer->GetSockName(sockAddr);
- GetAddress( sockAddr, strAddr );
- //AppendText( _T("Server Running on: %s\r\n"), strAddr);
- }
- void IServerImpl::OnThreadExit(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- //AppendText( _T("Server Down!\r\n"));
- }
- void IServerImpl::OnConnectionFailure(CSocketHandle* pSH, SOCKET newSocket)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr;
- CSocketHandle sockHandle;
- SockAddrIn sockAddr;
- if (newSocket != INVALID_SOCKET)
- {
- sockHandle.Attach( newSocket );
- sockHandle.GetPeerName( sockAddr );
- GetAddress( sockAddr, strAddr );
- sockHandle.Close();
- //AppendText( _T("Connection abandoned: %s\r\n"), strAddr );
- //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned:%s",strAddr));
- //OutputDebugString(_T("\n客户端连接中断:"));
- //OutputDebugString(strAddr);
- //OutputDebugString(_T("\n\n"));
- }
- else
- {
- //OutputDebugString(_T("\n客户端连接中断,不是一个有效的套接字:"));
- //OutputDebugString(strAddr);
- //OutputDebugString(_T("\n\n"));
- //AppendText( _T("Connection abandoned. Not a valid socket.\r\n"), strAddr );
- //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned. Not a valid socket:%s",strAddr));
- }
- }
- void IServerImpl::OnAddConnection(CSocketHandle* pSH, SOCKET newSocket)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr;
- CSocketHandle sockHandle;
- SockAddrIn sockAddr;
- sockHandle.Attach( newSocket );
- sockHandle.GetPeerName( sockAddr );
- GetAddress( sockAddr, strAddr );
- sockHandle.Detach();
- //OutputDebugString(_T("\n新的连接接入:"));
- //OutputDebugString(strAddr);
- //OutputDebugString(_T("\n"));
- //LOG4C_NO_FILENUM((LOG_NOTICE,"新的连接接入:%s",strAddr));
- //AppendText( _T("Connection established: %s\r\n"), strAddr );
- }
- void IServerImpl::OnDataReceived(CSocketHandle* pSH, const SOCKET sClient, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr, BYTE **pendingbuf, unsigned int& npendingSize, unsigned int& ncursize)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr, strText;
- //USES_CONVERSION;
- //LPTSTR pszText = strText.GetBuffer(dwCount+1);
- //::StringCchCopyN(pszText, dwCount+1, A2CT(reinterpret_cast<LPCSTR>(pbData)), dwCount);
- //strText.ReleaseBuffer();
- GetAddress( addr, strAddr );
- //AppendText( _T("%s>(%s)\r\n"), strAddr, strText);
- const SocketContextList& sl = m_SocketServer.GetClientSocketList();
- CClientProcess::GetInstance()->ClientProcess(sClient, pbData, dwCount, strAddr, pendingbuf, npendingSize, ncursize);
- }
- void IServerImpl::OnConnectionDropped(CSocketHandle* pSH)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr;
- CSocketHandle sockHandle;
- SockAddrIn sockAddr;
- //sockHandle.Attach( pSH->GetSocket() );
- sockHandle.GetPeerName( sockAddr );
- GetAddress( sockAddr, strAddr );
- //sockHandle.Detach();
- //AppendText( _T("Connection lost with client.\r\n") );
- //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection lost with client"));
- }
- void IServerImpl::OnConnectionError(CSocketHandle* pSH, DWORD dwError)
- {
- ASSERT( pSH == m_SocketServer );
- (pSH);
- _com_error err(dwError);
- //AppendText( _T("Communication Error:\r\n%s\r\n"), err.ErrorMessage() );
- CString strAddr;
- CSocketHandle sockHandle;
- SockAddrIn sockAddr;
- sockHandle.GetPeerName( sockAddr );
- GetAddress( sockAddr, strAddr );
- //LOG4C((LOG_NOTICE,"IP:%s Communication Error:%s", strAddr, err.ErrorMessage()));
- }
- #if defined(SOCKHANDLE_USE_OVERLAPPED)
- void IServerImpl::OnRemoveConnection(CSocketHandle* pSH, SOCKET dropSocket)
- {
- return;
- ASSERT( pSH == m_SocketServer );
- (pSH);
- CString strAddr;
- CSocketHandle sockHandle;
- SockAddrIn sockAddr;
- sockHandle.Attach( dropSocket );
- sockHandle.GetPeerName( sockAddr );
- GetAddress( sockAddr, strAddr );
- sockHandle.Detach();
- //LOG4C_NO_FILENUM((LOG_NOTICE,"Connection abandoned. Not a valid socket:%s",strAddr));
- }
- #endif
- DWORD IServerImpl::GetClientConnectCount()
- {
- //DWORD dwClientSize = 0;
- //m_SocketServer->GetConnectionCount();
- return m_SocketServer.GetConnectionCount();
- }
- void IServerImpl::StartClearInvalidateSocketThread()
- {
- m_hRunObject = CreateEvent( NULL, TRUE, FALSE, _T("ClearInvalidateSocketThread") );
- if ( m_hRunObject == NULL )
- {
- // LOG4C((LOG_NOTICE,"创建事件失败"));
- }
- m_hClearInvalidateSocketThread = CreateThread(NULL,0,ClearInvalidateSocketThread,this,0,NULL);
- if ( m_hClearInvalidateSocketThread == NULL )
- {
- // LOG4C((LOG_NOTICE,"创建线程失败"));
- }
- }
- DWORD WINAPI IServerImpl::ClearInvalidateSocketThread(void *pInstance)
- {
- //LOG4C((LOG_NOTICE,"服务端心跳检测线程"));
- IServerImpl *pServerImpl = (IServerImpl*)pInstance;
- #ifdef SOCKHANDLE_USE_OVERLAPPED
- /*const*/ SocketContextList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
- SocketContextList::iterator citer = sl.begin();
- #else
- /*const*/ SocketList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
- SocketList::const_iterator citer = sl.begin();
- #endif
- //SockAddrIn sockAddr;
- //size_t nSize = sl.size();
- DWORD dwError;
- //CSocketHandle tSocketHandle;
- do
- {
- //nSize = sl.size();
- if ( !pServerImpl->m_bStopbeat )
- {
- //AutoThreadSection aSenction(pServerImpl->m_SocketServer.ReturnSection());
- //if( (nSize != 0) && (citer != sl.end()))
- if ( citer != sl.end())
- {
- //SocketIOBuffer *buf = citer;
- DWORD dwTick = GetTickCount();
- //if ( ( dwTick - citer->dwTime) > 5000 )
- //{
- SOCKET sokt = static_cast<SOCKET>(*citer++);
-
- WORD wMessageId = MSG_LOGIN_RESP;
- LOGIN_RESULT_STRU tLoginResult = {0};
- tLoginResult.tCommonMsg.dwConnectionID = 0;
- tLoginResult.tCommonMsg.wMessageId = wMessageId;
- tLoginResult.byResult = LOGIN_RESULT_SUC;
- tLoginResult.dwUserID = 0;
- tLoginResult.byStatus = USER_STATUS_ONLINE ;
- DWORD dwDataLen = sizeof(LOGIN_RESULT_STRU);
- TMessageHeader tHeader = {0};
- tHeader.wMessageId = wMessageId;
- tHeader.dwDataLen = dwDataLen;
- CSocketHandle hClient;
- hClient.Attach(sokt);
- INT nRet = CClientProcess::net_Send(&hClient, &tHeader, (void *)&tLoginResult, dwDataLen);
- hClient.Detach();
- if ( nRet <= 0 )
- {
- pServerImpl->m_SocketServer.RemoveConnection(sokt);
- pServerImpl->m_SocketServer.CloseConnection(sokt);
- }
- //}
- //else
- //{
- // citer++;
- //}
- //tSocketHandle.Attach( (*citer) );
- #if 0
- //tSocketHandle.Write(LPBYTE("0"), 1, NULL, 30000); // 心跳包超时值:30秒到1分钟为好!
- dwError = WSAGetLastError();
- switch( dwError )
- {
- case WSAENOTSOCK:
- case WSAENETDOWN:
- case WSAENETUNREACH:
- case WSAENETRESET:
- case WSAECONNABORTED:
- case WSAECONNRESET:
- case WSAESHUTDOWN:
- case WSAEHOSTDOWN:
- case WSAEHOSTUNREACH:
- //citer = sl.erase(citer);
- LOG4C_NO_FILENUM((LOG_NOTICE,"删除过期客户端连接"));
- //pServerImpl->m_SocketServer.CloseConnection(*citer);
- //pServerImpl->m_SocketServer.RemoveConnection(*citer);
- citer = sl.begin();
- default:
- //TRACE("--------------%d\r\n",dwError);
- if( citer != sl.end() )
- citer++;
- break;
- }
- #endif
- //tSocketHandle.Detach();
- }
- else if ( citer == sl.end() )
- {
- citer = sl.begin();
- }
- }
- } while (WaitForSingleObject(pServerImpl->m_hRunObject,5000L) == WAIT_TIMEOUT);
- return 0;
- }
- };
|