#include "StdAfx.h"
#include "IServerImpl.h"
#include <comdef.h>
#include <atlbase.h>
#include "ThreadPool.hpp"

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)
	{
		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)))
		{
			AfxMessageBox(_T("Failed to start server."), NULL, MB_ICONSTOP);
		}
		//SyncControls();
	}

	void IServerImpl::Stop()
	{
		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 SocketBufferList& sl = m_SocketServer.GetSocketList();
				for(SocketBufferList::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::ProcessData(CSocketHandle &sockHandle, const BYTE* pData, DWORD nDataLen)
	{
		DWORD nBuffIndex = 0;

		while( nBuffIndex < nDataLen )
		{
			//LOG4C((LOG_NOTICE, "接收长度=%d, 处理长度=%d, PendingSize=%d", nLen, nBuffIndex, sockHandle.m_nPendingSize)); 
			STProtocolheader *pHeader;   //当前协议包头
			DWORD nProcessedLen = 0;   //当前循环处理了多少个字节

			if( sockHandle.m_nPendingSize > 0 )		// 开始组包
			{
				//LOG4C((LOG_NOTICE, "开始组包"));
				pHeader = (STProtocolheader *)sockHandle.m_PendingBuffer;
				if( sockHandle.m_nPendingSize < sizeof(STProtocolheader) )	//上一次接收到的长度小于包头
				{
					DWORD nLinkHeaderLen = sizeof( STProtocolheader ) - sockHandle.m_nPendingSize;
					if( nLinkHeaderLen < nDataLen )		//这次可以收完包头	
					{
						memcpy( &sockHandle.m_PendingBuffer[sockHandle.m_nPendingSize], pData, nLinkHeaderLen );   //这里已经收完Header
						nProcessedLen = pHeader->nDataLen - sockHandle.m_nPendingSize;
						if( nProcessedLen <= nDataLen )  //如果所需处理的长度小于等于当前包长度
						{
							memcpy( &sockHandle.m_PendingBuffer[sizeof(STProtocolheader)],&((char *)pData )[nLinkHeaderLen],pHeader->nDataLen - sizeof(STProtocolheader) );
							//LOG4C((LOG_NOTICE, "收完所需的包"));
						}
						else
						{
							int nTemp = nDataLen - nLinkHeaderLen; //除去头剩余部分的长度
							if ( nTemp > 0 )	//刚好是Header的长度，不用拷贝内存，所以这里加了>0的判断
							{
								memcpy( &sockHandle.m_PendingBuffer[sizeof(STProtocolheader)],&((char *)pData)[nLinkHeaderLen],nTemp );
							}
							sockHandle.m_nPendingSize += nDataLen;
						}
					}
					else   //这次还是没有收完包头， 继续Pending
					{
						//LOG4C((LOG_NOTICE, "这次还是没有收完包头， 继续Pending"));
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_nPendingSize ], pData, nDataLen );
						sockHandle.m_nPendingSize += nDataLen;
						nProcessedLen = nDataLen;
					}
				}
				else //Header部分已经在阻塞的缓冲区中
				{
					nProcessedLen = pHeader->nDataLen - sockHandle.m_nPendingSize;
					if ( nProcessedLen <= nDataLen ) //如果需要处理的长度小于现有包的长度
					{
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_nPendingSize ], pData, nProcessedLen );
						sockHandle.m_nPendingSize = 0;
					}
					else //否则要继续阻塞
					{
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_nPendingSize ], pData, nDataLen );
						sockHandle.m_nPendingSize += nDataLen;
					}
				}
			}
			else	//第一次接包
			{
				//LOG4C((LOG_NOTICE, "第一次接包"));
				pHeader = (STProtocolheader *)&((unsigned char *)pData)[nBuffIndex];
				if( nDataLen - nBuffIndex < sizeof(STProtocolheader) )	// 没有收够包头，先记录当前收到的Buffer 
				{
					//如果第一次接包就没有收够包头，认为是非法包，扔掉，就是说已处理的长度nProcessedLen = 0
					sockHandle.m_nPendingSize = nDataLen - nBuffIndex;
					memcpy(sockHandle.m_PendingBuffer, pHeader, sockHandle.m_nPendingSize);
					//LOG4C((LOG_NOTICE, "第一次接包就没有收够包头，认为是非法包，扔掉"));
				}
				else
				{
					nProcessedLen = pHeader->nDataLen;
					if( (int)pHeader->nDataLen > nDataLen - nBuffIndex )    
					{
						memcpy(sockHandle.m_PendingBuffer, pHeader, nDataLen - nBuffIndex);
						//如果第一次接包，pHeader->nDataLen大于当前包的总长，认为是非法包，扔掉
						if( nBuffIndex == 0 )   
						{
							//组包错误，则扔掉当前包
							//LOG4C((LOG_NOTICE, "第一次接包，服务器pHeader->nDataLen大于当前包的总长，认为是非法包，扔掉\r\n"));
						}
						sockHandle.m_nPendingSize = nDataLen - nBuffIndex;
						nProcessedLen = nDataLen - nBuffIndex;
					}
					else
					{
						//LOG4C((LOG_NOTICE, "正常包"));
						sockHandle.m_nPendingSize = 0;
					}
				}
			}

			if ( nProcessedLen == 0 )
			{
				// 没有收够包头，认为是非法包，扔掉
				//LOG4C((LOG_NOTICE, "没有收够包头，认为是非法包，扔掉"));
				break;
			}

			if ( sockHandle.m_nPendingSize == 0 )
			{
				if ( pHeader->nDataLen > SOCKET_BUFFSIZE ) // Jeff.undo it;
				{
					// Jeff.包长度超过限制,暂时不处理,因为确实会有超过限制的,除非强制实施该限制;
					//LOG4C((LOG_NOTICE, "pHeader->nLen超过限制"));
				}

				if ( pHeader->bof != PBOF )	// Jeff.2014.08.09.用于校验包头标识;
				{
					// 非法包;
					memset(sockHandle.m_PendingBuffer,0,sockHandle.m_nPendingSize);
					sockHandle.m_nPendingSize = 0;
					break;
				}

				if(-1 == OnCmdProcess( sockHandle, pHeader ))
				{
//				//	LOG4C((LOG_NOTICE, "Error OnCmdProcess"));
					break;
				}
			}

			nBuffIndex += nProcessedLen;
			//LOG4C((LOG_NOTICE, "处理长度=%d, PendingSize=%d", nBuffIndex, sockHandle.m_nPendingSize)); 
		}
	}


	void IServerImpl::ManipulationData(IN CSocketHandle &sockHandle, IN const BYTE* pData, IN DWORD nDataLen)
	{
		DWORD nBuffIndex = 0;

		while( nBuffIndex < nDataLen )
		{
			//LOG4C((LOG_NOTICE, "接收长度=%d, 处理长度=%d, PendingSize=%d", nLen, nBuffIndex, sockHandle.m_dwPendingSize)); 
			STProtocolheader *pHeader;		// 当前协议包头
			DWORD nProcessedLen = 0;		// 当前循环处理了多少个字节

			if( sockHandle.m_dwPendingSize > 0 )		// 开始组包
			{
				//LOG4C((LOG_NOTICE, "开始组包"));
				pHeader = (STProtocolheader *)sockHandle.m_PendingBuffer;
				if( sockHandle.m_dwPendingSize < sizeof(STProtocolheader) )	//上一次接收到的长度小于包头
				{
					DWORD nLinkHeaderLen = sizeof( STProtocolheader ) - sockHandle.m_dwPendingSize;
					if( nLinkHeaderLen < nDataLen )		//这次可以收完包头	
					{
						memcpy( &sockHandle.m_PendingBuffer[sockHandle.m_dwPendingSize], pData, nLinkHeaderLen );   //这里已经收完Header
						nProcessedLen = CALCDATALEN(pHeader->nDataLen) - sockHandle.m_dwPendingSize;
						if( nProcessedLen <= nDataLen )  //如果所需处理的长度小于等于当前包长度
						{
							memcpy( &sockHandle.m_PendingBuffer[sizeof(STProtocolheader)],&((char *)pData )[nLinkHeaderLen],CALCDATALEN(pHeader->nDataLen) - sizeof(STProtocolheader) );
							//LOG4C((LOG_NOTICE, "收完所需的包"));
						}
						else
						{
							int nTemp = nDataLen - nLinkHeaderLen; //除去头剩余部分的长度
							if ( nTemp > 0 )	//刚好是Header的长度，不用拷贝内存，所以这里加了>0的判断
							{
								memcpy( &sockHandle.m_PendingBuffer[sizeof(STProtocolheader)],&((char *)pData)[nLinkHeaderLen],nTemp );
							}
							sockHandle.m_dwPendingSize += nDataLen;
						}
					}
					else   //这次还是没有收完包头， 继续Pending
					{
						//LOG4C((LOG_NOTICE, "这次还是没有收完包头， 继续Pending"));
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_dwPendingSize ], pData, nDataLen );
						sockHandle.m_dwPendingSize += nDataLen;
						nProcessedLen = nDataLen;
					}
				}
				else //Header部分已经在阻塞的缓冲区中
				{
					nProcessedLen = CALCDATALEN(pHeader->nDataLen) - sockHandle.m_dwPendingSize;
					if ( nProcessedLen <= nDataLen ) //如果需要处理的长度小于现有包的长度
					{
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_dwPendingSize ], pData, nProcessedLen );
						sockHandle.m_dwPendingSize = 0;
					}
					else //否则要继续阻塞
					{
						memcpy( &sockHandle.m_PendingBuffer[ sockHandle.m_dwPendingSize ], pData, nDataLen );
						sockHandle.m_dwPendingSize += nDataLen;
					}
				}
			}
			else	//第一次接包
			{
				//LOG4C((LOG_NOTICE, "第一次接包"));
				pHeader = (STProtocolheader *)&((unsigned char *)pData)[nBuffIndex];
				if( nDataLen - nBuffIndex < sizeof(STProtocolheader) )	// 没有收够包头，先记录当前收到的Buffer 
				{
					//如果第一次接包就没有收够包头，认为是非法包，扔掉，就是说已处理的长度nProcessedLen = 0
					sockHandle.m_dwPendingSize = nDataLen - nBuffIndex;
					memcpy(sockHandle.m_PendingBuffer, pHeader, sockHandle.m_dwPendingSize);
					//LOG4C((LOG_NOTICE, "第一次接包就没有收够包头，认为是非法包，扔掉"));
				}
				else
				{
					nProcessedLen = CALCDATALEN(pHeader->nDataLen);
					if( (int)CALCDATALEN(pHeader->nDataLen) > nDataLen - nBuffIndex )    
					{
						memcpy(sockHandle.m_PendingBuffer, pHeader, nDataLen - nBuffIndex);
						//如果第一次接包，pHeader->nDataLen大于当前包的总长，认为是非法包，扔掉
						if( nBuffIndex == 0 )   
						{
							//组包错误，则扔掉当前包
							//LOG4C((LOG_NOTICE, "第一次接包，服务器pHeader->nDataLen大于当前包的总长，认为是非法包，扔掉\r\n"));
						}
						sockHandle.m_dwPendingSize = nDataLen - nBuffIndex;
						nProcessedLen = nDataLen - nBuffIndex;
					}
					else
					{
						//LOG4C((LOG_NOTICE, "正常包"));
						sockHandle.m_dwPendingSize = 0;
					}
				}
			}

			if ( nProcessedLen == 0 )
			{
				// 没有收够包头，认为是非法包，扔掉
				//LOG4C((LOG_NOTICE, "没有收够包头，认为是非法包，扔掉"));
				break;
			}

			if ( sockHandle.m_dwPendingSize == 0 )
			{
				if ( CALCDATALEN(pHeader->nDataLen) > SOCKET_BUFFSIZE ) // Jeff.undo it;
				{
					// Jeff.包长度超过限制,暂时不处理,因为确实会有超过限制的,除非强制实施该限制;
					//LOG4C((LOG_NOTICE, "pHeader->nLen超过限制"));
				}

				if ( pHeader->bof != PBOF )	// Jeff.2014.08.09.用于校验包头标识;
				{
					// 非法包;
					memset(sockHandle.m_PendingBuffer,0,sockHandle.m_dwPendingSize);
					sockHandle.m_dwPendingSize = 0;
					break;
				}

				if(-1 == OnCmdManipulation( sockHandle, pHeader ))
				{
					//				//	LOG4C((LOG_NOTICE, "Error OnCmdProcess"));
					break;
				}
			}

			nBuffIndex += nProcessedLen;
			//LOG4C((LOG_NOTICE, "处理长度=%d, PendingSize=%d", nBuffIndex, sockHandle.m_dwPendingSize)); 
		}
	}


	int IServerImpl::OnCmdProcess(CSocketHandle &sockHandle, void *pData)
	{
		STProtocolheader *pHeader = (STProtocolheader *)pData;

		if( pHeader == NULL )
			return -1;

		if( pHeader->nDataLen < 0 || pHeader->nDataLen > 65535 ) 
			return -1;

		unsigned int tmp = CalcCheckSum(pHeader, pHeader->nDataLen);
		if(tmp != pHeader->nVerify)  
		{	
			return -1;
		}

		switch (pHeader->nCmd)              
		{
		case 1:
			break;
		default: return 0;
		}
		return 0;
	}

	int IServerImpl::OnCmdManipulation(IN CSocketHandle &sockHandle, IN void *pData)
	{
		STProtocolheader *pHeader = (STProtocolheader *)pData;

		if( pHeader == NULL )
			return -1;

		if( CALCDATALEN(pHeader->nDataLen) < 0 || CALCDATALEN(pHeader->nDataLen) > 65535 ) 
			return -1;

		unsigned int tmp = CalcCheckSum(pHeader, pHeader->nDataLen);
		if(tmp != pHeader->nVerify)  
		{	
			return -1;
		}

		switch (pHeader->nCmd)              
		{
		case 1:
			break;
		default: return 0;
		}
		return 0;
	}

	void IServerImpl::ToprocessRecivebuf(IN CSocketHandle &sockHandle, IN const BYTE* pReceivebuf, IN DWORD dwReceiveSize)
	{
		STProtocolheader *pHeader;
		if ( sockHandle.m_npendingSize == 0 )
		{
			pHeader = (STProtocolheader *)(pReceivebuf);

			if ( dwReceiveSize < pHeader->nDataLen )	// 不足一个完整包;
			{
				sockHandle.m_npendingSize = dwReceiveSize + sizeof(STProtocolheader);
				memcpy(sockHandle.m_szpendingbuf,pReceivebuf,sockHandle.m_npendingSize);
			}
			else if ( dwReceiveSize >= pHeader->nDataLen )	// 粘包;	
			{
				if( -1 == OnIntegrityPacket(sockHandle,pHeader))
				{
					;
				}

				// 处理剩余数据;
				sockHandle.m_npendingSize = dwReceiveSize - sizeof(STProtocolheader) - pHeader->nDataLen;
				if(sockHandle.m_npendingSize != 0)
					memcpy(sockHandle.m_szpendingbuf,pReceivebuf+sizeof(STProtocolheader)+pHeader->nDataLen,sockHandle.m_npendingSize);
			}
		}
		else if ( sockHandle.m_npendingSize > 0 )
		{
			pHeader = (STProtocolheader *)sockHandle.m_szpendingbuf;
			
			if ( sockHandle.m_npendingSize > pHeader->nDataLen+sizeof(STProtocolheader) )
			{
				// 异常处理:出现缓存数据大于完整包数据长度;
			}

			if ( pHeader->nDataLen+sizeof(STProtocolheader) - sockHandle.m_npendingSize > dwReceiveSize )	// 还是没有收够一个完整的包;
			{
				memcpy(sockHandle.m_szpendingbuf+sockHandle.m_npendingSize,pReceivebuf,dwReceiveSize);
				sockHandle.m_npendingSize += dwReceiveSize;
			}
			else if ( pHeader->nDataLen+sizeof(STProtocolheader) - sockHandle.m_npendingSize <= dwReceiveSize )	// 收够完整的包;
			{
				// 完整的包;
				memcpy(sockHandle.m_szpendingbuf+sockHandle.m_npendingSize,pReceivebuf,pHeader->nDataLen+sizeof(STProtocolheader) - sockHandle.m_npendingSize);
				sockHandle.m_npendingSize += dwReceiveSize - pHeader->nDataLen;
				if( -1 == OnIntegrityPacket(sockHandle,pHeader))
				{
					;
				}

				// 处理剩余数据;
				memset(sockHandle.m_szpendingbuf,0,sockHandle.m_npendingSize);
				if ( sockHandle.m_npendingSize != 0)
					memcpy(sockHandle.m_szpendingbuf,pReceivebuf+dwReceiveSize-sockHandle.m_npendingSize,sockHandle.m_npendingSize);
			}
		}
	}

	int IServerImpl::OnIntegrityPacket(IN CSocketHandle &sockHandle, IN void *pIntegrityPacket)
	{
		STProtocolheader *pHeader = (STProtocolheader *)pIntegrityPacket;

		if( pHeader == NULL || pHeader->bof != PBOF)
			return -1;

		if( pHeader->nDataLen < 0 || pHeader->nDataLen > 65535 ) 
			return -1;

		unsigned int tmp = VerityIntegrityPacket(pHeader, pHeader->nDataLen);
		if(tmp != pHeader->nVerify)  
		{	
			return -1;
		}

		switch (pHeader->nCmd)
		{
		case CMD_TOCHAT:
			{
				STChatbody *tChatbody = (STChatbody*)pIntegrityPacket;
				TRACE("------------------");
				AfxMessageBox(tChatbody->szChat);
			}
			break;
		default: return 0;
		}

		return 0;
	}

	unsigned int IServerImpl::VerityIntegrityPacket(IN void *pIntegrityPacket,unsigned int nPacketSize)
	{
		unsigned int checksum = 0;
		unsigned char *pBody = &((unsigned char*)pIntegrityPacket)[sizeof(STProtocolheader)];

		if( pBody )
			checksum = crc32( 0, pBody, nPacketSize );

		return checksum;
	}

	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 );
		}
		else
		{
			AppendText( _T("Connection abandoned. Not a valid socket.\r\n"), 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();
		AppendText( _T("Connection established: %s\r\n"), strAddr );
	}

	void IServerImpl::OnDataReceived(CSocketHandle* pSH, const BYTE* pbData, DWORD dwCount, const SockAddrIn& addr)
	{
		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);

		if (m_nSockType == SOCK_TCP)
		{
			// unsafe access to Socket list!
#ifdef SOCKHANDLE_USE_OVERLAPPED
			const SocketBufferList& sl = m_SocketServer.GetSocketList();
			for(SocketBufferList::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
			{
				EnterCriticalSection( &m_csProcessData );
				CSocketHandle sockHandle;
				sockHandle.m_nPendingSize = 0;
				memset(sockHandle.m_PendingBuffer, 0, SOCKET_BUFFSIZE);
				sockHandle.Attach( (*citer) );
				SockAddrIn sockAddr;
				sockHandle.GetPeerName(sockAddr);
				if( sockAddr == addr )
				{
					//ProcessData( sockHandle, pbData, dwCount );
					ToprocessRecivebuf(sockHandle,pbData,dwCount);
				}
				sockHandle.Detach();
				LeaveCriticalSection( &m_csProcessData );
			}
		}
		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") );
			}
		}
	}

	void IServerImpl::OnConnectionDropped(CSocketHandle* pSH)
	{
		ASSERT( pSH == m_SocketServer );
		(pSH);
		AppendText( _T("Connection lost with client.\r\n") );
	}

	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() );
	}
};