#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)
	{
		m_bStopbeat = FALSE;
		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);
		}
		//else StartClearInvalidateSocketThread();
		//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;
			}
		}

		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 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::ToprocessRecivebuf(IN SocketIOBuffer &sockHandle, IN const BYTE* pReceivebuf, IN DWORD dwReceiveSize)
	{
		DWORD dwIndexOfProcessed = 0;		// 当前接收的包被处理的长度;
		DWORD dwOnceProcessedLen = 0;		// 循环一次处理了多少当前包;
		STProtocolheader *pstProtocolheader;

		//LOG4C((LOG_NOTICE,"当前包大小：%d 内容：%s",dwReceiveSize,pReceivebuf));
		//LOG4C((LOG_NOTICE,"缓存包大小：%d,内容：%s",sockHandle.npendingSize,sockHandle.szpendingbuf));
		while( dwIndexOfProcessed < dwReceiveSize)
		{
			pstProtocolheader = NULL;
			dwOnceProcessedLen = 0;

			if ( sockHandle.npendingSize == 0)	//----------------------------------------------// 1.第一次接收或完整组包后接收剩余包;
			{
				//pstProtocolheader = (STProtocolheader *)&((unsigned char *)pReceivebuf)[dwIndexOfProcessed];
				//LOG4C((LOG_NOTICE, "1.第一次接收或完整组包后接收剩余包"));
				if( dwReceiveSize - dwIndexOfProcessed < sizeof(STProtocolheader) )					// 1.1.第一次接收或剩余数据不足一个包头;
				{
					//LOG4C((LOG_NOTICE, "1.1.第一次接收或剩余数据不足一个包头"));
					// 如果第一次接包就没有收够包头，认为是非法包，扔掉，就是说已处理的长度dwOnceProcessedLen = 0;
					sockHandle.npendingSize = dwReceiveSize - dwIndexOfProcessed;
					//memcpy(sockHandle.szpendingbuf, pstProtocolheader, sockHandle.npendingSize);
					memcpy(sockHandle.szpendingbuf, &pReceivebuf[dwIndexOfProcessed], sockHandle.npendingSize);

					dwOnceProcessedLen = dwReceiveSize - dwIndexOfProcessed;
				}
				else																				// 1.2.第一次接收或剩余数据大于一个包头;
				{
					pstProtocolheader = (STProtocolheader *)&((unsigned char *)pReceivebuf)[dwIndexOfProcessed];
					//LOG4C((LOG_NOTICE, "1.2.第一次接收或剩余数据大于一个包头,协议包长度：%d",pstProtocolheader->nDataLen));
					//dwOnceProcessedLen = pstProtocolheader->nDataLen;
					if( (int)pstProtocolheader->nDataLen > dwReceiveSize - dwIndexOfProcessed )		// 1.2.1.第一次接收或剩余数据不足一个完整的协议包;
					{//
						//LOG4C((LOG_NOTICE, "1.2.1.第一次接收或剩余数据不足一个完整的协议包"));
						//memcpy(sockHandle.szpendingbuf, pstProtocolheader, dwReceiveSize - dwIndexOfProcessed);
						memcpy(sockHandle.szpendingbuf, &pReceivebuf[dwIndexOfProcessed], dwReceiveSize - dwIndexOfProcessed);
						//如果第一次接包，pstProtocolheader->nDataLen大于当前包的总长，认为是非法包，扔掉(不处理这部分，不一定是非法包)
// 						if( dwIndexOfProcessed == 0 )   
// 						{
// 							//组包错误，则扔掉当前包
// 							LOG4C((LOG_NOTICE, "第一次接包，服务器pstProtocolheader->nDataLen大于当前包的总长，认为是非法包，扔掉"));
// 						}
						sockHandle.npendingSize = dwReceiveSize - dwIndexOfProcessed;
						dwOnceProcessedLen = dwReceiveSize - dwIndexOfProcessed;	// 该次处理的数据长度;
					}
					else	// ---------------------------------------------------------------------// 1.2.2.第一次接收或剩余数据大于一个完整的协议包;
					{
						//LOG4C((LOG_NOTICE, "1.2.2.第一次接收或剩余数据大于一个完整的协议包"));
						sockHandle.npendingSize = 0;
						//memset(sockHandle.szpendingbuf,0,SOCKET_BUFFSIZE);
						dwOnceProcessedLen = pstProtocolheader->nDataLen;	// 该次处理的数据长度;
					}
				}
			}
			else if( sockHandle.npendingSize > 0)	//------------------------------------------------------------------------------// 2.第n+1次接收数据包;
			{
				if( sockHandle.npendingSize < sizeof(STProtocolheader) )	// 2.1.pengingbuf数据小于包头
				{
					//LOG4C((LOG_NOTICE,"2.1.pengingbuf数据小于包头"));
					DWORD dwRestheader = sizeof(STProtocolheader) - sockHandle.npendingSize;
					if( dwRestheader < dwReceiveSize )							// 2.1.1.当前包大小 > 剩下包头长度,可以组成一个完整包头;	
					{
						//LOG4C((LOG_NOTICE,"2.1.1.当前包大小 > 剩下包头长度,可以组成一个完整包头"));
						// -1.先收完一个完整的包头;
						memcpy( &sockHandle.szpendingbuf[sockHandle.npendingSize], pReceivebuf, dwRestheader);

						//LOG4C((LOG_NOTICE,"2.1.1.当前包大小 > 剩下包头长度,可以组成一个完整包头,协议包长度：%d",pstProtocolheader->nDataLen));
						// -2.处理剩余数据;
						pstProtocolheader = (STProtocolheader *)sockHandle.szpendingbuf;
						dwOnceProcessedLen = pstProtocolheader->nDataLen - sockHandle.npendingSize;
						if( dwOnceProcessedLen <= dwReceiveSize )  // 2.1.1.1.可以组成一个完整的协议包;
						{
							//LOG4C((LOG_NOTICE,"2.1.1.1.可以组成一个完整的协议包"));
							memcpy( &sockHandle.szpendingbuf[sizeof(STProtocolheader)],
								&((char *)pReceivebuf)[dwRestheader],
								pstProtocolheader->nDataLen - sizeof(STProtocolheader));

							sockHandle.npendingSize = 0;
						}
						else	// 2.1.1.2.未能组成一个完整的协议包,断续接收等待;
						{
							//int nTemp = dwReceiveSize - dwRestheader; //除去头剩余部分的长度
							//if ( nTemp > 0 )	//刚好是Header的长度，不用拷贝内存，所以这里加了>0的判断
							//{
							//memcpy( &pSockHandle->m_szpendingbuf[sizeof(STProtocolheader)],&((char *)pReceivebuf)[dwRestheader],nTemp );
							//}
							//LOG4C((LOG_NOTICE,"2.1.1.2.未能组成一个完整的协议包,断续接收等待"));
							memcpy( &sockHandle.szpendingbuf[sizeof(STProtocolheader)],&((char *)pReceivebuf)[dwRestheader],dwReceiveSize - dwRestheader);
							sockHandle.npendingSize += dwReceiveSize;
						}
					}
					else //------------------------------------------------------// 2.1.2.当前包大小 <= 剩下包头长度,未能或刚好组成一个完整的包头;
					{
						//LOG4C((LOG_NOTICE,"2.1.2.当前包大小 <= 剩下包头长度,未能或刚好组成一个完整的包头"));
						memcpy( &sockHandle.szpendingbuf[sockHandle.npendingSize], pReceivebuf, dwReceiveSize );
						sockHandle.npendingSize += dwReceiveSize;
						dwOnceProcessedLen = dwReceiveSize;
					}
				}
				else // --------------------------------------------------------// 2.2.pengingbuf数据大于包头;
				{
					pstProtocolheader = (STProtocolheader *)sockHandle.szpendingbuf;
					dwOnceProcessedLen = pstProtocolheader->nDataLen - sockHandle.npendingSize;
					if ( dwOnceProcessedLen <= dwReceiveSize )		// 可以组成一个完整的协议包;
					{
						//LOG4C((LOG_NOTICE,"2.2.1.可以组成一个完整的协议包"));
						memcpy( &sockHandle.szpendingbuf[sockHandle.npendingSize], pReceivebuf, dwOnceProcessedLen );
						sockHandle.npendingSize = 0;
						//memset(sockHandle.szpendingbuf,0,SOCKET_BUFFSIZE);
					}
					else // 未能组成一个完整协议包;
					{
						//LOG4C((LOG_NOTICE,"2.2.2.未能组成一个完整协议包"));
						memcpy( &sockHandle.szpendingbuf[sockHandle.npendingSize], pReceivebuf, dwReceiveSize );
						sockHandle.npendingSize += dwReceiveSize;
					}
				}
			}

			//LOG4C((LOG_NOTICE,"*********%d,%s",sockHandle.npendingSize,sockHandle.szpendingbuf));
			if ( dwOnceProcessedLen == 0 )	
			{
				// 没有收够包头，认为是非法包，扔掉
				LOG4C((LOG_NOTICE, "*****没有收够包头，认为是非法包，扔掉"));
				break;
			}

			if ( sockHandle.npendingSize == 0 )
			{
				//LOG4C((LOG_NOTICE, "ok.处理完整协议包的解析工作"));
				if ( pstProtocolheader->nDataLen > SOCKET_BUFFSIZE )
				{
					// 包长度超过限制,暂时不处理;
					LOG4C((LOG_NOTICE, "pstProtocolheader->nDataLen超过限制"));
				}

				if(-1 == OnIntegrityPacket(sockHandle, pstProtocolheader))
				{
					LOG4C((LOG_NOTICE, "Error OnIntegrityPacket"));
					memset(sockHandle.szpendingbuf,0,sockHandle.npendingSize);
					sockHandle.npendingSize = 0;
					break;
				}
			}

			//LOG4C((LOG_NOTICE,"//////////%d,%s",sockHandle.npendingSize,sockHandle.szpendingbuf));
			dwIndexOfProcessed += dwOnceProcessedLen;
		}
	}

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

		if( pHeader == NULL )
		{
			LOG4C((LOG_NOTICE,"pHeader == NULL"));
			return -1;
		}

		if( pHeader->bof != PBOF)
		{
			LOG4C((LOG_NOTICE,"协议头标识错误"));
			return -1;
		}

		//if( pHeader->nDataLen < 0 || pHeader->nDataLen > 65535 ) 
		if( pHeader->nDataLen > 1024*1024 ) 
		{
			LOG4C((LOG_NOTICE,"协议长度越界错误"));
			return -1;
		}

		unsigned int tmp = VerifyIntegrityPacket(pHeader, pHeader->nDataLen);

		//LOG4C((LOG_NOTICE,"协议标识:%d,协议命令:%d,协议类型:%d,协议长度:%d,协议校验:%d",pHeader->bof,pHeader->nCmd,pHeader->nCmdType,pHeader->nDataLen,pHeader->nVerify));

		//unsigned char *pBody = &((unsigned char*)pIntegrityPacket)[sizeof(STProtocolheader)];

		if(tmp != pHeader->nVerify)  
		{	
			LOG4C((LOG_NOTICE,"协议校验值错误:len=%d,%d != %d",pHeader->nDataLen,tmp,pHeader->nVerify));
			return -1;
		}

		switch (pHeader->nCmd)
		{
		case CMD_HEART:		// 公共命令：心跳包
			{
				// 心跳包,不处理任务事务;
				LOG4C((LOG_NOTICE,"接收到的心跳包"));
			}
			break;
		case CMD_TOCHAT:	// 公共命令：文字聊天;
			{
				STChatbody *tChatbody = (STChatbody*)pIntegrityPacket;
				//TRACE("------------------");
				//AfxMessageBox(tChatbody->szChat);
// 				CStdioFile fp;
// 				CString path = CString(g_ModulePath) + _T("1111.txt");
// 				if (PathFileExists(path))
// 				{
// 					fp.Open(path, CFile::modeWrite);
// 					ULONGLONG length = fp.GetLength();
// 					if (length > 5 * 1024 * 1024)
// 					{
// 						fp.Close();
// 						::DeleteFile(path);
// 						return -1;
// 					}
// 					fp.SeekToEnd();
// 				}
// 				else
// 					fp.Open(path, CFile::modeCreate | CFile::modeWrite);
// 
// 				fp.WriteString((CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S")) + _T(" ") + tChatbody->szChat + _T("\n")));
// 				fp.Close();
				//LOG4C((LOG_NOTICE,"聊天内容：%s",tChatbody->szChat));
			}
			break;
		case CMD_FILEINFO_TRANSFER:	// 公共命令：文件传输;
			{
				//LOG4C((LOG_NOTICE,"文件信息传输"));
				// 需要向客户端返回本地文件的信息：
				// 1.若不存在指定文件名,则返回FileSeek = 0;（文件位置指针）
				// 2.若文件存在,则读取文件大小,如果文件大小 == 客户端文件大小,表示已有完整文件，不进行传输;
				// 3.若文件存在,但文件大小 < 客户端文件大小,认为没有传守文件,继传。
				// 4.若文件存在,但文件大小 > 客户端文件大小,先删除本地文件,再与1相同处理。

				// 服务端要维护一个文件列表,用于记录客户端需要传输的文件;
				// 客户端同样维护一个文件列表,用于记录要传输的文件;

				// 两边文件列表一致;

				g_dwRecived = 0;

				if ( g_pSTFileInfobody == NULL )
				{
					g_pSTFileInfobody = new STFileInfobody();
				}

				memset(g_pSTFileInfobody,0,sizeof(STFileInfobody));
				memcpy(g_pSTFileInfobody,pIntegrityPacket,sizeof(STFileInfobody));
				//g_pSTFileInfobody = (STFileInfobody*)pIntegrityPacket;


				LOG4C((LOG_NOTICE,"%d:%d:%d:%d:%d, %s:%d:%d:%d",
					g_pSTFileInfobody->tPHeader.bof,
					g_pSTFileInfobody->tPHeader.nCmd,
					g_pSTFileInfobody->tPHeader.nCmdType,
					g_pSTFileInfobody->tPHeader.nDataLen,
					g_pSTFileInfobody->tPHeader.nVerify,
					g_pSTFileInfobody->szFileName,
					g_pSTFileInfobody->nFileLength,
					g_pSTFileInfobody->tCreateDate,
					g_pSTFileInfobody->tModifyDate));

				TCHAR szFileFullName[MAX_PATH] = _T("");
				sprintf(szFileFullName,"%s\%s",g_ModulePath,g_pSTFileInfobody->szFileName);
				memcpy(g_pSTFileInfobody->szFileName,szFileFullName,MAX_PATH);
				LOG4C((LOG_NOTICE,"文件名：%s",g_pSTFileInfobody->szFileName));
			}
			break;
		case CMD_FILECONT_TRANSFER:
			{
				//LOG4C((LOG_NOTICE,"文件内容传输"));

				// 文件传输需要单独出一个端口来独立完成，且只接收客户端排队文件传输。
				if ( g_pSTFileInfobody == NULL )
				{
					LOG4C((LOG_NOTICE,"接收文件信息失败"));
					return 0;
				}

				CFile file;
				CFileException e;
				file.Open(g_pSTFileInfobody->szFileName, CFile::modeNoTruncate|CFile::modeWrite|CFile::modeCreate|CFile::shareExclusive, &e);
				if (e.m_cause != 0)
				{
					DWORD dw = GetLastError();
					LOG4C((LOG_NOTICE,"创建或打开文件失败:%d",dw));	// dw = 53,表示写文件的速度还不及收的速度快。上次未写完，这次又要开始打开文件写.
					file.Close();
					return -1;
				}

				STFileContextbody *pFileContextbody = (STFileContextbody*)pIntegrityPacket;

				//__int64 nTotal = 0;
				//while( g_dwRecived < g_STFileInfobody.nFileLength )
				//{
				file.SeekToEnd();
				file.Write(pFileContextbody->szFileContext, pFileContextbody->nFileContextLen);
				g_dwRecived += pHeader->nDataLen;
				//}

				file.Close();
				//CFile::SetStatus(xInfo.szFileName,xInfo.fStat);
			}
			break;
		case C2LCMD_REQ_LOGIN:
			{
				// 1.判断登录信息（加密狗信息）;
				// 2.信息从数据库中获取,比对正常允许通信;
				// **3.若信息比对失败,断开连接;
				// 3.若信息比对失败,允许连接,但不返回数据库信息;
				// 本端可对其进行控制。
			}
			break;
		case C2CCMD_REQ_LOGIN:
			{
				// 1.判断登录信息（账号+密码）;
				// 2.信息从数据库中获取,比对正常允许通信,并返回数据库信息;
				// 3.若信息比对失败,断开连接;
				STAccountInfobody *tAccountInfobody = (STAccountInfobody*)pIntegrityPacket;

				if ( (strcmp(tAccountInfobody->szAccount,_T("admin")) == 0) && (strcmp(tAccountInfobody->szPassword,_T("admin123456")) == 0) )
				{
					TRACE("账号信息完全匹配");
					LOG4C((LOG_NOTICE,"账号信息完全匹配"));
					// 临时步骤,数据库信息应该做为全局变量保存; g_STDatabaseInfobody;
					STDatabaseInfobody tDatabaseInfobody;
					// ....配置好数据库信息;
					// ....................
					strcpy(tDatabaseInfobody.szDatabaseServer,"127.0.0.1");
					strcpy(tDatabaseInfobody.szDatabaseTCPPort,"1433");
					strcpy(tDatabaseInfobody.szDatabaseAccount,"sa");
					strcpy(tDatabaseInfobody.szDatabasePassword,"ly1234");
					strcpy(tDatabaseInfobody.szDatabaseName,"db");

					tDatabaseInfobody.GetVerify();
					//m_SocketServer->Write();
					CSocketHandle tSockhandle;
					tSockhandle.Attach(sockHandle);
					m_bStopbeat = TRUE;//停止心跳包;
					if( -1 == tSockhandle.Write((const LPBYTE)(&tDatabaseInfobody), tDatabaseInfobody.tPHeader.nDataLen, NULL))  
					{
						// 发送失败;
						LOG4C((LOG_NOTICE,"发送失败ooo"));
						tSockhandle.Detach();
					}
					tSockhandle.Detach();
					m_bStopbeat = FALSE;//恢复心跳包;
				}
				else
				{
					TRACE("账号或密码错误");
					LOG4C((LOG_NOTICE,"账号或密码错误,关闭该套接字,拒绝连接"));
					// 关闭该套接字,拒绝连接;
					CSocketHandle::ShutdownConnection(sockHandle);
				}
			}
			break;
		default: return 0;
		}

		memset(sockHandle.szpendingbuf,0,SOCKET_BUFFSIZE);

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

		//LOG4C((LOG_NOTICE,"新的连接接入：%s",strAddr));
		//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 );
//#if 0
//				CSocketHandle sockHandle;
//				sockHandle.m_npendingSize = 0;
//				memset(sockHandle.m_szpendingbuf, 0, SOCKET_BUFFSIZE);
//				sockHandle.Attach( (*citer) );
//				SockAddrIn sockAddr;
//				sockHandle.GetPeerName(sockAddr);
//				if( sockAddr == addr )
//				{
//					ToprocessRecivebuf(sockHandle,pbData,dwCount);
//				}
//				sockHandle.Detach();
//#else
//				if ( addr == SockAddrIn(*citer))
//				{
//					ToprocessRecivebuf(*citer,pbData,dwCount);
//				}
//#endif
//				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::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 );
				if ( addr == SockAddrIn(*citer))
				{
					ToprocessRecivebuf((SocketIOBuffer&)*citer,pbData,dwCount);
				}
				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") );
		LOG4C((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() );
		LOG4C((LOG_NOTICE,"Communication Error：%s",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((LOG_NOTICE,"删除无效连接：%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, "ClearInvalidateSocketThread" );
		if ( m_hRunObject == NULL )	
		{
			LOG4C((LOG_NOTICE,"创建事件失败"));
		}

		m_hClearInvalidateSocketThread = CreateThread(NULL,0,ClearInvalidateSocketThread,this,0,NULL);
		if ( m_hClearInvalidateSocketThread == NULL )	
		{
			LOG4C((LOG_NOTICE,"创建线程失败"));
		}
	}

	// 这个线程不能做到安全删除无用的客户端;
	// 会删除其他线程正在使用的socket,造成崩溃问题.
	DWORD WINAPI IServerImpl::ClearInvalidateSocketThread(void *pInstance)
	{
		LOG4C((LOG_NOTICE,"服务端心跳检测线程"));
		IServerImpl *pServerImpl = (IServerImpl*)pInstance;

#ifdef SOCKHANDLE_USE_OVERLAPPED
		/*const*/ SocketBufferList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
		SocketBufferList::const_iterator citer = sl.begin();
#else
		/*const*/ SocketList& sl = pServerImpl->m_SocketServer.GetClientSocketList();
		SocketList::const_iterator citer = sl.begin();
#endif

#if 0
		STProtocolheader tProtocolheader;
		tProtocolheader.nVerify = VerityIntegrityPacket(&tProtocolheader, sizeof(STProtocolheader));
#else
		STChatbody tChatbody;
		memset(tChatbody.szChat,97,MAX_CHATLENGTH);
		//tChatbody.tPHeader.nVerify = VerifyIntegrityPacket(&tChatbody, sizeof(STChatbody));
		tChatbody.GetVerify();
#endif
		//SockAddrIn sockAddr;
		//size_t nSize = sl.size();
		//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())
				{
					//tSocketHandle.Attach( (*citer) );

					//if( -1 == tSocketHandle.Write((const LPBYTE)(&tProtocolheader), tProtocolheader.nDataLen, sockAddr))  
					//if( -1 == tSocketHandle.Write((const LPBYTE)(&tProtocolheader), tProtocolheader.nDataLen, NULL))  
					if( -1 == send(*citer,(const char*)(&tChatbody),tChatbody.tPHeader.nDataLen,NULL))
					//if( -1 == tSocketHandle.Write((const LPBYTE)(&tChatbody), tChatbody.tPHeader.nDataLen, NULL))  
					{
						//CString strAddr;
						//SockAddrIn sockAddr = SockAddrIn(*citer);
						//pServerImpl->GetAddress( sockAddr, strAddr );
						LOG4C((LOG_NOTICE,"服务端开始删除无效SOCKET"));
						//tSocketHandle.Close();
						//citer = sl.erase(citer);
						//tSocketHandle.Detach();
						//pServerImpl->m_SocketServer.RemoveConnection(tSocketHandle.GetSocket());
						//pServerImpl->m_SocketServer.CloseConnection(tSocketHandle.GetSocket());
						pServerImpl->m_SocketServer.RemoveConnection(*citer);
						pServerImpl->m_SocketServer.CloseConnection(*citer);
						LOG4C((LOG_NOTICE,"服务端成功删除无效SOCKET"));
						//tSocketHandle.Detach();

						citer = sl.begin();
						continue;
					}
					else
					{
						citer++;
					}

					//tSocketHandle.Detach();
				}
				else if ( citer == sl.end() )
				{
					citer = sl.begin();
				}
			}
		} while (WaitForSingleObject(pServerImpl->m_hRunObject,150L) == WAIT_TIMEOUT);
		return 0;
	}
};
