📄 arwinclient_t.cpp
字号:
#include "ArWinClient_T.h"
#include <stdio.h>
#include <process.h>
#define ENABLE_MUTICAST
static const char* MULTICAST_IP = "224.0.0.99";
HANDLE ArWinClient_T::m_hHeap = 0;
//----------------------------------------------------------------
ArWinClient_T::ArWinClient_T(void* pPara)
{
m_bExitThread = false;
m_bConnected = false;
m_bIsDestroy = false;
m_pReceiveDataFunc = NULL;
m_pConnectFunc = NULL;
m_pDisConnectFunc = NULL;
m_pPara = pPara;
m_iMaxReceiveDataLength = 1024 * 4;
if(0 == m_hHeap)
{
m_hHeap = ::HeapCreate(0, 1024, 0);
}
m_iMaxDataBufferSize = MAX_DATA_BUFFER_SIZE;
m_iMaxMsgBufferSize = MAX_MSG_SIZE;
m_iMaxMultCastMsgSize = MAX_MUTICAST_MSG_SIZE;
//设置Socket的属性
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_CLIENT_DATA_BUFFER);
//m_hOpenClientEvent = ::CreateEvent(NULL, true, false,NULL);
m_bCreate = false;
m_bIsServerDisconnect = false;
m_bAutoDisconnect = false;
m_pThreadDisconnect = 0;
}
//----------------------------------------------------------------
ArWinClient_T::~ArWinClient_T()
{
//::CloseHandle(m_hOpenClientEvent);
if(m_pThreadDisconnect)
{
if(::WaitForSingleObject(m_pThreadDisconnect, 500) != WAIT_OBJECT_0)
{
::TerminateThread(m_pThreadDisconnect, 0);
};
}
}
//------------------------------------------------------------------------------
bool __stdcall ArWinClient_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 ArWinClient_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 ArWinClient_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 ArWinClient_T::Create(unsigned long ulAddress, int iPort)
{
m_ulAddress = ulAddress;
m_iPort = iPort;
m_ServerAddr.sin_family = AF_INET;
m_ServerAddr.sin_addr.S_un.S_addr = ulAddress;
m_ServerAddr.sin_port = htons(m_iPort);
m_MessageServerAddr.sin_family = AF_INET;
m_MessageServerAddr.sin_addr.S_un.S_addr = ulAddress;
m_MessageServerAddr.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_LocalMessageAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
m_LocalMessageAddr.sin_family = AF_INET;
m_LocalMessageAddr.sin_port = htons(m_iPort + 4);
m_SenderInfo.iPort = iPort;
m_SenderInfo.ulAddress = ulAddress;
return true;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::Destroy(void)
{
m_bIsDestroy = true;
Close();
return true;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::Open(void)
{
if(m_bCreate)
{
return false;
}
if(CreateSocket() == false)
{
return false;
}
unsigned int uiThreadID;
m_uiOpenClientThread = _beginthreadex(NULL, 0, StartConect,(void*)this, 0, &uiThreadID);
m_bCreate = true;
m_bAutoDisconnect = false;
return true;
}
//------------------------------------------------------------------------------
bool __stdcall ArWinClient_T::SetMutiCastAdrr(int iAddr)
{
return true;
}
//----------------------------------------------------------------
unsigned int __stdcall ArWinClient_T::StartConect(void* pParent)
{
ArWinClient_T* pClient = (ArWinClient_T*)pParent;
while(true)
{
if(pClient->OpenClient())
{
if(pClient->m_pConnectFunc)
{
(*pClient->m_pConnectFunc)(pClient->m_SenderInfo, pClient->m_pPara);
}
break;
}
Sleep(300);
}
return 0;
}
//----------------------------------------------------------------
bool ArWinClient_T::OpenClient(void)
{
if(true == m_bConnected)
{
return true;
}
//连接成功,打开数据流,多播,数据报三个线程
if(connect(m_DataSocket, (struct sockaddr*)&m_ServerAddr,
sizeof(m_ServerAddr) ) == SOCKET_ERROR)
{
return false;
}
unsigned int uiThreadID;
m_uiMultiCastThread = _beginthreadex(NULL, 0, SocketMultiCast,(void*)this, 0, &uiThreadID);
m_uiMessageThread = _beginthreadex(NULL, 0, SocketMessage,(void*)this, 0, &uiThreadID);
m_uiReceiveThread = _beginthreadex(NULL, 0, ReceiveData,(void*)this, 0, &uiThreadID);
m_SenderInfo.ulAddress = m_ServerAddr.sin_addr.S_un.S_addr;
m_bConnected = true;
return true;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::Close(void)
{
if(false == m_bConnected)
{
return false;
}
m_bCreate = false;
m_bExitThread = true;
m_bConnected = false;
m_bAutoDisconnect = true;
closesocket(m_DataSocket);
closesocket(m_MessageSocket);
closesocket(m_MultiCastSocket);
WSASetEvent(m_DataSocketPara.Overlapped.hEvent);
WSASetEvent(m_MessageSocketPara.Overlapped.hEvent);
WSASetEvent(m_MulitCastSocketPara.Overlapped.hEvent);
if(::WaitForSingleObject((void*)m_uiMultiCastThread, 10000) == WAIT_TIMEOUT)
{
::TerminateThread((void*)m_uiMultiCastThread, 0);
};
if(::WaitForSingleObject((void*)m_uiMessageThread, 10000) == WAIT_TIMEOUT)
{
::TerminateThread((void*)m_uiMessageThread, 0);
}
if(::WaitForSingleObject((void*)m_uiReceiveThread, 50000) == WAIT_TIMEOUT)
{
::TerminateThread((void*)m_uiReceiveThread, 0);
}
/*if(m_pDisConnectFunc)
{
m_pDisConnectFunc(m_SenderInfo, m_pPara);
}*/
return true;
}
//----------------------------------------------------------------
int __stdcall ArWinClient_T::SendData(char* pcData, int iLength)
{
if(false == m_bConnected)
{
return 0;
}
/*if(iLength < 224)
{
return (SendDataPackage(pcData, iLength));
}*/
int iData;
ArDataPackage_T DataPackage;
DataPackage.ucType = DATA;
DataPackage.iDataSize = iLength;
for(int i = 0; i < 58; i++)
{
DataPackage.ucVerify[i] = i % 3;
}
int iSendDataSize = sizeof(ArDataPackage_T) + iLength;
memcpy(m_pcDataSendBuffer, &DataPackage, sizeof(ArDataPackage_T));
memcpy(m_pcDataSendBuffer + sizeof(ArDataPackage_T), pcData, iLength);
iData = send(m_DataSocket, m_pcDataSendBuffer, iSendDataSize, 0) ;
return iData;
}
//----------------------------------------------------------------
int __stdcall ArWinClient_T::SendDataPackage(char* pcData, int iLength)
{
if(NULL == pcData)
{
iLength = 0;
}
if(iLength + sizeof(ArDataPackage_T) >= ArWinClient_T::MAX_MSG_SIZE)
{
iLength = ArWinClient_T::MAX_MSG_SIZE - sizeof(ArDataPackage_T);
}
ArDataPackage_T DataPackage;
DataPackage.ucType = DATA;
DataPackage.iDataSize = iLength;
memcpy(m_SendMessagerBuffer, &DataPackage, sizeof(DataPackage));
if(iLength > 0)
{
memcpy(m_SendMessagerBuffer + sizeof(DataPackage), pcData, iLength);
}
int iDataNum = 0;
iDataNum = sendto(m_MessageSocket, m_SendMessagerBuffer,
sizeof(DataPackage) + DataPackage.iDataSize, 0,
(const struct sockaddr*)&m_MessageServerAddr,
sizeof(m_MessageServerAddr));
return iDataNum;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::OnReceiveData(pOnReceiveData func)
{
m_pReceiveDataFunc = func;
return true;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::OnConnect(pOnConnect func)
{
m_pConnectFunc = func;
return true;
}
//----------------------------------------------------------------
bool __stdcall ArWinClient_T::OnDisconnect(pOnConnect func)
{
m_pDisConnectFunc = func;
return true;
}
//----------------------------------------------------------------
void ArWinClient_T::DrestroyClientHeap()
{
if(m_hHeap)
{
::HeapDestroy(m_hHeap);
}
}
//----------------------------------------------------------------
unsigned int __stdcall ArWinClient_T::ServerDisConnect(void* pParent)
{
ArWinClient_T* pClient = (ArWinClient_T*)pParent;
if(pClient->m_pDisConnectFunc && false == pClient->m_bAutoDisconnect)
{
pClient->m_pDisConnectFunc(pClient->m_SenderInfo, pClient->m_pPara);
Sleep(1000);
pClient->Close();
pClient->Open();
}
return 0;
}
//----------------------------------------------------------------
unsigned int __stdcall ArWinClient_T::ReceiveData(void* pParent)
{
ArWinClient_T* pClient = (ArWinClient_T*)pParent;
ArRunInfo_T RunInfo;
RunInfo.bStartRead = false;
RunInfo.iHasRead = 0;
RunInfo.pcData = NULL;
RunInfo.pcData = (char*)::HeapAlloc(pClient->m_hHeap, 0,pClient->m_iMaxReceiveDataLength);
pClient->m_DataSocketPara.pBuffer= (char*)::HeapAlloc(pClient->m_hHeap, 0, pClient->m_iMaxDataBufferSize);
pClient->m_DataSocketPara.DataBuf.buf = pClient->m_DataSocketPara.pBuffer;
pClient->m_DataSocketPara.DataBuf.len = pClient->m_iMaxDataBufferSize;
ZeroMemory(&pClient->m_DataSocketPara.Overlapped, sizeof(OVERLAPPED));
pClient->m_DataSocketPara.Overlapped.hEvent = WSACreateEvent();
while(true)
{
DWORD RecvBytes;
DWORD Flags;
Flags = 0;
if (WSARecv(pClient->m_DataSocket,
&(pClient->m_DataSocketPara.DataBuf), 1,
&RecvBytes, &Flags,
&(pClient->m_DataSocketPara.Overlapped),
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
break;
}
}
if ( WSAWaitForMultipleEvents(1, &pClient->m_DataSocketPara.Overlapped.hEvent, FALSE,
WSA_INFINITE, FALSE) == WSA_WAIT_FAILED)
{
break;
}
WSAResetEvent(pClient->m_DataSocketPara.Overlapped.hEvent);
DWORD BytesTransferred;
if (WSAGetOverlappedResult(pClient->m_DataSocket,
&(pClient->m_DataSocketPara.Overlapped),
&BytesTransferred,
FALSE, &Flags) == FALSE )
{
unsigned int uiThreadID;
pClient->m_pThreadDisconnect =
(void*)_beginthreadex(NULL, 0, ServerDisConnect,(void*)pClient, 0, &uiThreadID);
/*if(pClient->m_pDisConnectFunc && false == pClient->m_bIsDestroy)
{
pClient->m_pDisConnectFunc(pClient->m_SenderInfo, pClient->m_pPara);
}*/
closesocket(pClient->m_MultiCastSocket);
closesocket(pClient->m_DataSocket);
closesocket(pClient->m_MessageSocket);
pClient->m_bIsServerDisconnect = true;
break;
}
if(BytesTransferred )
{
if(RunInfo.bStartRead == true)
{
memcpy(RunInfo.pcData + RunInfo.iHasRead, pClient->m_DataSocketPara.DataBuf.buf, BytesTransferred);
RunInfo.iHasRead += BytesTransferred;
}
if(RunInfo.bStartRead == false && BytesTransferred >= sizeof(ArDataPackage_T))
{
memcpy(&RunInfo.DataReceive, pClient->m_DataSocketPara.DataBuf.buf, sizeof(ArDataPackage_T));
bool bRightPkg = true;
if(RunInfo.DataReceive.ucType != DATA)
{
bRightPkg = false;
}
for(int i = 0; i < 58; i++)
{
if(RunInfo.DataReceive.ucVerify[i] != i % 3)
{
bRightPkg = false;
}
}
if( bRightPkg && RunInfo.DataReceive.iDataSize > 0)
{
if(pClient->m_iMaxReceiveDataLength < RunInfo.DataReceive.iDataSize)
{
::HeapFree(pClient->m_hHeap, 0, RunInfo.pcData);
RunInfo.pcData = (char*)::HeapAlloc(pClient->m_hHeap, 0,RunInfo.DataReceive.iDataSize);
}
RunInfo.bStartRead = true;
memcpy(RunInfo.pcData, pClient->m_DataSocketPara.DataBuf.buf + sizeof(ArDataPackage_T),
BytesTransferred - sizeof(ArDataPackage_T));
RunInfo.iHasRead = BytesTransferred - sizeof(ArDataPackage_T);
}
}
}
if(RunInfo.bStartRead == true
&& RunInfo.DataReceive.iDataSize
&& RunInfo.iHasRead >= RunInfo.DataReceive.iDataSize)
{
RunInfo.bStartRead = false;
int iRead =RunInfo.DataReceive.iDataSize;
RunInfo.iHasRead = 0;
if(pClient->m_pReceiveDataFunc)
{
pClient->m_pReceiveDataFunc(RunInfo.pcData, iRead, pClient->m_SenderInfo, pClient->m_pPara);
}
}
}
WSACloseEvent(pClient->m_DataSocketPara.Overlapped.hEvent);
::HeapFree(pClient->m_hHeap, 0, RunInfo.pcData);
::HeapFree(pClient->m_hHeap, 0,pClient->m_DataSocketPara.pBuffer);
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -