📄 arwinserver_t.cpp
字号:
#include "ArWinServer_T.h"
#include <process.h>
#include <mswsock.h>
#define ENABLE_MUTICAST
static const char* MULTICAST_IP = "224.0.0.99";
HANDLE ArWinServer_T::m_hHeap = 0;
//------------------------------------------------------------------------------
ArWinServer_T::ArWinServer_T(void* pPara)
{
m_pPara = pPara;
m_iMaxClientNum = 20;
m_pOnReceiveFunc = NULL;
m_pOnReceiveFunc = NULL;
m_pOnConnect = NULL;
m_pOnDisConnect = NULL;
m_iConnectClientNum = 0;
m_iMaxConnectClientNum = 0;
m_bOpen = false;
m_bServerExit = false;
m_bIsDestroy = false;
m_ConnectClientInfoList.clear();
if(0 == m_hHeap)
{
m_hHeap = ::HeapCreate(0, 1024, 0);
}
m_iMaxReceiveDataLength = 1024;
SetMutiCastAdrr(99);
m_EventArray[0] = WSACreateEvent();
if(WSA_INVALID_EVENT == m_EventArray[0])
{
::MessageBox(NULL, "初始化m_EventArray[0]出错!", "Error!", MB_OK);
}
m_hConnectEvent = ::CreateEvent(NULL, false, true, NULL);
m_hDisConnectEvent = ::CreateEvent(NULL, false, true, NULL);
m_iMaxDataBufferSize = MAX_DATA_BUFFER_SIZE;
m_iMaxMsgBufferSize = MAX_MSG_SIZE;
m_iMaxMultCastMsgSize = MAX_MUTICAST_MSG_SIZE;
m_bDataHasRcvBuffer = true;
m_bDataHasSendBuffer = true;
m_bDataEnableLinger = true;
m_bMessageHasRcvBuffer = true;
m_bMessageHasSendBuffer = true;
m_bMessageEnableLinger = true;
m_bMultiCastHasRcvBuffer = true;
m_bMultiCastHasSendBuffer = true;
m_bMultiCastEnableLinger = true;
m_pcDataSendBuffer = (char*)HeapAlloc(m_hHeap, 0, MAX_SERVER_DATA_BUFFER);
m_pThreadOnClientDisconnect = 0;
m_bIsDestroy = false;
}
//------------------------------------------------------------------------------
ArWinServer_T::~ArWinServer_T()
{
if(::WaitForSingleObject((void*)m_pThreadOnClientDisconnect, 500) != WAIT_OBJECT_0)
{
::TerminateThread((void*)m_pThreadOnClientDisconnect, 0);
}
}
//------------------------------------------------------------------------------
void ArWinServer_T::DestroyServerHeap(void)
{
if(m_hHeap)
{
::HeapDestroy(m_hHeap);
}
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T::SetDataSocketOpt(bool bHasRcvBuffer, bool bHasSndBuffer,
bool bEnableLinger, int iUserRcvBufferLen)
{
m_bDataHasRcvBuffer = bHasRcvBuffer;
m_bDataHasSendBuffer = bHasSndBuffer;
m_bDataEnableLinger = bEnableLinger;
if(iUserRcvBufferLen > MAX_DATA_BUFFER_SIZE)
{
iUserRcvBufferLen = MAX_DATA_BUFFER_SIZE;
}
m_iMaxDataBufferSize = iUserRcvBufferLen;
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T::SetMessageSocketOpt(bool bHasRcvBuffer, bool bHasSndBuffer,
bool bEnableLinger, int iUserRcvBufferLen)
{
m_bMessageHasRcvBuffer = bHasRcvBuffer;
m_bMessageHasSendBuffer = bHasSndBuffer;
m_bMessageEnableLinger = bEnableLinger;
if(iUserRcvBufferLen > MAX_MSG_SIZE)
{
iUserRcvBufferLen = MAX_MSG_SIZE;
}
m_iMaxMsgBufferSize = iUserRcvBufferLen;
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T::SetMutiCastSocketOpt(bool bHasRcvBuffer, bool bHasSndBuffer,
bool bEnableLinger, int iUserRcvBufferLen)
{
m_bMultiCastHasRcvBuffer = bHasRcvBuffer;
m_bMultiCastHasSendBuffer = bHasSndBuffer;
m_bMultiCastEnableLinger = bEnableLinger;
if(iUserRcvBufferLen > MAX_MUTICAST_MSG_SIZE)
{
iUserRcvBufferLen = MAX_MUTICAST_MSG_SIZE;
}
m_iMaxMultCastMsgSize = iUserRcvBufferLen;
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T::SetMutiCastAdrr(int iAddr)
{
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T:: Open(void)
{
if(m_bOpen == true)
{
return false;
}
WSAResetEvent(m_EventArray[0]);
m_ConnectClientInfoList.clear();
if(CreateSocket() == false)
{
return false;
}
m_bOpen = true;
m_bFirstCreate = false;
unsigned int uiThreadID;
m_ulThreadReadData = _beginthreadex(NULL, 0, WaitForData,(void*)this, 0, &uiThreadID);
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T:: Close(void)
{
if(false == m_bOpen)
{
return false;
}
DestroyAllClient();
m_bServerExit = true;
WSASetEvent(m_MessageSocketPara.Overlapped.hEvent);
WSASetEvent(m_ListenSocketPara.Overlapped.hEvent);
WSASetEvent(m_EventArray[0]);
closesocket(m_ListenSocket);
closesocket(m_MessageSocket);
closesocket(m_MultiCastSocket);
Sleep(200);
m_bOpen = false;
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T:: Create(int iPort)
{
m_bInitialOk = false;
m_MessageSocketPara.pBuffer = (char*)::HeapAlloc(m_hHeap, 0, m_iMaxMsgBufferSize);
m_ListenSocketPara.pBuffer = (char*)::HeapAlloc(m_hHeap, 0, m_iMaxDataBufferSize);
m_iPort = iPort;
m_LocalAdrr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
m_LocalAdrr.sin_family = AF_INET;
m_LocalAdrr.sin_port = htons(m_iPort);
m_LocalMessageAdrr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
m_LocalMessageAdrr.sin_family = AF_INET;
m_LocalMessageAdrr.sin_port = htons(m_iPort + 1);
m_MutiCastAdrr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
m_MutiCastAdrr.sin_family = AF_INET;
m_MutiCastAdrr.sin_port = htons(m_iPort + 2);
m_bInitialOk = true;
m_bOpen = false;
m_bFirstCreate = true;
return true;
}
//------------------------------------------------------------------------------
unsigned int __stdcall ArWinServer_T::SoketListenning(void* pParent)
{
ArWinServer_T* pServer = (ArWinServer_T*)pParent;
pServer->StartListenning();
return 0;
}
//------------------------------------------------------------------------------
void ArWinServer_T::StartListenning(void)
{
while(true)
{
ArClientInfo_T* pSocketInfo = (ArClientInfo_T*)::HeapAlloc(m_hHeap, 0, sizeof(ArClientInfo_T));
pSocketInfo->ConnectSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,WSA_FLAG_OVERLAPPED);
if(INVALID_SOCKET == pSocketInfo->ConnectSocket)
{
continue;
}
ZeroMemory(&m_ListenSocketPara.Overlapped, sizeof(OVERLAPPED));
m_ListenSocketPara.Overlapped.hEvent = WSACreateEvent();
if(WSA_INVALID_EVENT == m_ListenSocketPara.Overlapped.hEvent)
{
continue;
}
ZeroMemory(m_ListenSocketPara.pBuffer, m_iMaxDataBufferSize);
DWORD Bytes;
if (AcceptEx(m_ListenSocket, pSocketInfo->ConnectSocket ,
(PVOID) m_ListenSocketPara.pBuffer, 0,
sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &Bytes,
&m_ListenSocketPara.Overlapped) == FALSE)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
break;
}
}
if ( WSAWaitForMultipleEvents(1, &m_ListenSocketPara.Overlapped.hEvent, FALSE,
WSA_INFINITE, FALSE) == WSA_WAIT_FAILED)
{
break;
}
WSAResetEvent(m_ListenSocketPara.Overlapped.hEvent);
DWORD BytesTransferred;
DWORD Flags = 0;
if (WSAGetOverlappedResult(m_ListenSocket, &(m_ListenSocketPara.Overlapped), &BytesTransferred,
FALSE, &Flags) == FALSE)
{
break;
}
struct sockaddr* pLocalAddr;
struct sockaddr* pClientAddr;
int iLocalLength;
int iClientAddrLength;
struct sockaddr_in ClientAddr;
int iSize = sizeof(ClientAddr);
GetAcceptExSockaddrs(m_ListenSocketPara.pBuffer, 0,
sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16,
&pLocalAddr, &iLocalLength,&pClientAddr,
&iClientAddrLength);
ClientAddr = *((sockaddr_in*)pClientAddr);
setsockopt( pSocketInfo->ConnectSocket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char*)&( m_ListenSocket ), sizeof( m_ListenSocket ) );
if(false == m_bDataHasRcvBuffer)
{
int iRcvBufferSize = 0;
setsockopt(pSocketInfo->ConnectSocket, SOL_SOCKET,SO_RCVBUF, (char*)&iRcvBufferSize, sizeof(iRcvBufferSize));
}
if(false == m_bDataHasSendBuffer)
{
int iSendBufferSize = 0;
setsockopt(pSocketInfo->ConnectSocket, SOL_SOCKET,SO_SNDBUF, (char*)&iSendBufferSize, sizeof(iSendBufferSize));
}
if(true == m_bDataEnableLinger)
{
struct linger Linger;
Linger.l_linger = 2000;
Linger.l_onoff = true;
setsockopt(pSocketInfo->ConnectSocket, SOL_SOCKET,SO_LINGER, (char*)&Linger, sizeof(Linger));
}
else
{
struct linger Linger;
Linger.l_linger = 0;
Linger.l_onoff = false;
setsockopt(pSocketInfo->ConnectSocket, SOL_SOCKET,SO_LINGER, (char*)&Linger, sizeof(Linger));
}
pSocketInfo->SenderInfo.iPort = m_iPort;
pSocketInfo->SenderInfo.ulAddress = ClientAddr.sin_addr.S_un.S_addr;
pSocketInfo->hEvent = WSACreateEvent();
if(WSA_INVALID_EVENT == pSocketInfo->hEvent )
{
::MessageBox(NULL, "初始化pSocketInfo->hEvent出错!", "ServerError!", MB_OK);
}
pSocketInfo->pBuffer = (char*)HeapAlloc(m_hHeap, 0, m_iMaxDataBufferSize);
ZeroMemory(&pSocketInfo->Overlapped, sizeof(OVERLAPPED));
pSocketInfo->Overlapped.hEvent = pSocketInfo->hEvent;
pSocketInfo->DataBuf.buf = pSocketInfo->pBuffer;
pSocketInfo->DataBuf.len = m_iMaxDataBufferSize;
pSocketInfo->bHasRead = false;
pSocketInfo->bStartReceiveData = false;
pSocketInfo->iHasReadNum = 0;
pSocketInfo->iBufferSize = m_iMaxReceiveDataLength;
pSocketInfo->pcData = (char*)::HeapAlloc(m_hHeap, 0, m_iMaxReceiveDataLength);
m_ConnectClientInfoList.push_back(pSocketInfo);
m_iConnectClientNum = m_ConnectClientInfoList.size();
WSASetEvent(m_EventArray[0]);
if(m_pOnConnect)
{
m_pOnConnect(pSocketInfo->SenderInfo, m_pPara);
}
}
WSACloseEvent(m_ListenSocketPara.Overlapped.hEvent);
}
//------------------------------------------------------------------------------
unsigned int __stdcall ArWinServer_T::WaitForData(void* pParent)
{
ArWinServer_T* pServer = (ArWinServer_T*)pParent;
while(true)
{
std::list<ArClientInfo_T*>::iterator ClientPos;
ClientPos = pServer->m_ConnectClientInfoList.begin();
int iEventStartPos = 1;
ArClientInfo_T* pClient;
while(ClientPos != pServer->m_ConnectClientInfoList.end())
{
pClient = *ClientPos;
if(pClient->ConnectSocket && pClient->bHasRead == false)
{
DWORD RecvBytes;
DWORD Flags;
Flags = 0;
int iResult = WSARecv(pClient->ConnectSocket, &(pClient->DataBuf), 1,
&RecvBytes, &Flags, &(pClient->Overlapped), NULL);
if ( iResult == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
continue;
}
}
pClient->bHasRead = true;
}
pServer->m_EventArray[iEventStartPos] = pClient->hEvent;
iEventStartPos++;
ClientPos++;
}
int iClientNum = pServer->m_ConnectClientInfoList.size();
DWORD dwWaitResult = WSAWaitForMultipleEvents(iClientNum + 1, pServer->m_EventArray, FALSE,
WSA_INFINITE, FALSE);
if(dwWaitResult == WSA_WAIT_EVENT_0 )
{
WSAResetEvent(pServer->m_EventArray[dwWaitResult]);
/*if(pServer->m_bServerExit)
{
break;
}*/
continue;
}
if ( dwWaitResult == WSA_WAIT_FAILED)
{
break;
}
int iArrayIndex = dwWaitResult - WSA_WAIT_EVENT_0;
WSAResetEvent(pServer->m_EventArray[iArrayIndex]);
ArClientInfo_T* pFindClient = pServer->FindClient(pServer->m_EventArray[iArrayIndex]);
if(pFindClient == NULL)
{
continue;
}
DWORD BytesTransferred;
DWORD Flags;
Flags = 0;
if (WSAGetOverlappedResult(pFindClient->ConnectSocket,
&(pFindClient->Overlapped), &BytesTransferred,
FALSE, &Flags) == FALSE )
{
pServer->m_ConnectClientInfoList.remove(pFindClient);
if( pServer->m_pOnDisConnect && false == pServer->m_bIsDestroy)
{
pServer->m_pOnDisConnect(pFindClient->SenderInfo,
pServer->m_pPara);
}
closesocket(pFindClient->ConnectSocket);
WSACloseEvent(pFindClient->hEvent);
::HeapFree(pServer->m_hHeap,0, pFindClient->pcData);
::HeapFree(pServer->m_hHeap,0, pFindClient->pBuffer);
::HeapFree(pServer->m_hHeap,0, pFindClient);
continue;
}
pFindClient->bHasRead = false;
if(BytesTransferred )
{
if(pFindClient->bStartReceiveData == true)
{
memcpy(pFindClient->pcData + pFindClient->iHasReadNum,
pFindClient->DataBuf.buf, BytesTransferred);
pFindClient->iHasReadNum += BytesTransferred;
}
if(pFindClient->bStartReceiveData == false)
{
ArDataPackage_T DataReceive;
memcpy(&DataReceive, pFindClient->DataBuf.buf, sizeof(ArDataPackage_T));
pFindClient->iDataSize = DataReceive.iDataSize;
bool bRightPkg = true;
if(DataReceive.ucType != DATA)
{
bRightPkg = false;
}
for(int i = 0; i < 58; i++)
{
if(DataReceive.ucVerify[i] != i % 3)
{
bRightPkg = false;
}
}
if(bRightPkg && DataReceive.iDataSize > 0)
{
if(pFindClient->iBufferSize < DataReceive.iDataSize)
{
::HeapFree(pServer->m_hHeap, 0, pFindClient->pcData);
pFindClient->pcData = (char*)::HeapAlloc(pServer->m_hHeap, 0,DataReceive.iDataSize);
}
pFindClient->bStartReceiveData = true;
memcpy(pFindClient->pcData,
pFindClient->DataBuf.buf + sizeof(ArDataPackage_T),
BytesTransferred - sizeof(ArDataPackage_T));
pFindClient->iHasReadNum = BytesTransferred - sizeof(ArDataPackage_T);
}
}
}
if(pFindClient->bStartReceiveData &&
pFindClient->iDataSize &&
pFindClient->iHasReadNum >= pFindClient->iDataSize)
{
pFindClient->bStartReceiveData = false;
int iRead = pFindClient->iDataSize;
pFindClient->iHasReadNum = 0;
if(pServer->m_pOnReceiveFunc)
{
pServer->m_pOnReceiveFunc(pFindClient->pcData,
iRead,
pFindClient->SenderInfo,
pServer->m_pPara);
}
}
}
return 0;
}
//------------------------------------------------------------------------------
ArWinServer_T::ArClientInfo_T* ArWinServer_T::FindClient(WSAEVENT hEvent)
{
std::list<ArClientInfo_T*>::iterator ClientPos;
ClientPos = m_ConnectClientInfoList.begin();
ArClientInfo_T* pClient = NULL;
while(ClientPos != m_ConnectClientInfoList.end())
{
ArClientInfo_T* pTemp = *ClientPos;
if(hEvent == pTemp->hEvent)
{
pClient = pTemp;
break;
}
ClientPos++;
}
return pClient;
}
//------------------------------------------------------------------------------
bool ArWinServer_T::FindClient(unsigned long ulClientAddr, ArClientInfo_T& Info)
{
bool bResult = false;
std::list<ArClientInfo_T*>::iterator ClientPos;
ClientPos = m_ConnectClientInfoList.begin();
while(ClientPos != m_ConnectClientInfoList.end())
{
ArClientInfo_T* pTemp = *ClientPos;
if(ulClientAddr == pTemp->SenderInfo.ulAddress)
{
bResult = true;
memcpy(&Info ,pTemp, sizeof(ArClientInfo_T));
break;
}
ClientPos++;
}
return bResult;
}
//------------------------------------------------------------------------------
unsigned int __stdcall ArWinServer_T::SoketMessage(void* pParent)
{
ArWinServer_T* pServer = (ArWinServer_T*)pParent;
pServer->m_MessageSocketPara.pBuffer = (char*)::HeapAlloc(pServer->m_hHeap, 0, pServer->m_iMaxMsgBufferSize);
pServer->m_MessageSocketPara.DataBuf.buf = pServer->m_MessageSocketPara.pBuffer;
pServer->m_MessageSocketPara.DataBuf.len = pServer->m_iMaxMsgBufferSize;
ZeroMemory(&pServer->m_MessageSocketPara.Overlapped, sizeof(OVERLAPPED));
pServer->m_MessageSocketPara.Overlapped.hEvent = WSACreateEvent();
while(true)
{
DWORD RecvBytes;
DWORD Flags;
Flags = 0;
ArSenderInfo_T RemoteInfo;
struct sockaddr_in RemoteAdrr;
int iAddrSize = sizeof(RemoteAdrr);
if (WSARecvFrom (pServer->m_MessageSocket,
&(pServer->m_MessageSocketPara.DataBuf), 1,
&RecvBytes, &Flags,
(struct sockaddr*)&RemoteAdrr, &iAddrSize,
&(pServer->m_MessageSocketPara.Overlapped),
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
break;
}
}
if ( WSAWaitForMultipleEvents(1, &pServer->m_MessageSocketPara.Overlapped.hEvent, FALSE,
WSA_INFINITE, FALSE) == WSA_WAIT_FAILED)
{
break;
}
WSAResetEvent(pServer->m_MessageSocketPara.Overlapped.hEvent);
DWORD BytesTransferred;
if (WSAGetOverlappedResult(pServer->m_MessageSocket,
&(pServer->m_MessageSocketPara.Overlapped),
&BytesTransferred,
FALSE, &Flags) == FALSE )
{
continue;
}
RemoteInfo.iPort = RemoteAdrr.sin_port;
RemoteInfo.ulAddress = RemoteAdrr.sin_addr.S_un.S_addr;
ArDataPackage_T* pDataPackage = (ArDataPackage_T*)pServer->m_MessageSocketPara.DataBuf.buf;
if(pDataPackage->ucType == DATA)
{
char* pcReceiveData = pServer->m_MessageSocketPara.DataBuf.buf + sizeof(ArDataPackage_T);
if(pServer->m_pOnReceiveFunc)
{
pServer->m_pOnReceiveFunc(pcReceiveData,
pDataPackage->iDataSize,
RemoteInfo,
pServer->m_pPara);
}
}
}
WSACloseEvent(pServer->m_MessageSocketPara.Overlapped.hEvent);
return 0;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T:: Destroy(void)
{
m_bIsDestroy = true;
Close();
m_bIsDestroy = true;
WSACloseEvent(m_EventArray[0]);
::CloseHandle(m_hConnectEvent);
::CloseHandle(m_hDisConnectEvent);
return true;
}
//------------------------------------------------------------------------------
void ArWinServer_T::DisableAllClient(void)
{
}
//------------------------------------------------------------------------------
int __stdcall ArWinServer_T::ClientNum(void)
{
return (m_iConnectClientNum);
}
//------------------------------------------------------------------------------
bool __stdcall ArWinServer_T:: CloseClient(unsigned long ulClientAddr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -