📄 psgip.cpp
字号:
struct sockaddr_in sSockAddr;
struct hostent * psHostent;
DWORD dwAddr = 0;
char szIP[MAX_PATH], *pszAddr;
pszIP[0] = 0;
lError = gethostname(szIP, MAX_PATH);
if(lError)return lError;
psHostent = gethostbyname(szIP);
if(psHostent)
{
while(psHostent->h_addr_list[dwAddr])
{
memcpy(&(sSockAddr.sin_addr), psHostent->h_addr_list[dwAddr++], psHostent->h_length);
sSockAddr.sin_family = psHostent->h_addrtype;
pszAddr = inet_ntoa(sSockAddr.sin_addr);
strcat(pszIP, pszAddr);
strcat(pszIP, " ");
}
pszIP[strlen(pszIP) - 1] = 0;
lError = -((long)dwAddr);
}
else
{
dwAddr = inet_addr(szIP);
if(dwAddr == INADDR_NONE)
{
lError = ERROR_WS_UNABLE_RESOLVE;
return lError;
}
sSockAddr.sin_addr.s_addr = dwAddr;
sSockAddr.sin_family = AF_INET;
pszAddr = inet_ntoa(sSockAddr.sin_addr);
strcpy(pszIP, pszAddr);
lError = -1;
}
return lError;
}
STDMETHODIMP CPSgip::Init(long lPara, BSTR bStrSaveFile, long lReListenInterTimeStepIs1MS, BSTR bstrDebugPath, long *plError)
{
// TODO: Add your implementation code here
USES_CONVERSION;
*plError = ERROR_NOT;
int i;
DWORD dwRet;
char szPara[MAX_PATH];
if(m_bIsInit)
{
*plError = ERROR_ALREADY_INIT;
goto INIT_EXIT;
}
SYSTEMTIME sSystemTime4Para;
GetLocalTime(&sSystemTime4Para);
if(sSystemTime4Para.wMinute * 100 + sSystemTime4Para.wHour == lPara)
{
m_bIsEnableListen = true;
}
WSADATA wsaData;
struct sockaddr_in sSockAddr4Dest;
//startup
if (WSAStartup(MAKEWORD(2,1), &wsaData) != 0)
{
*plError = ERROR_WS_STARTUP_FAIL;
goto INIT_EXIT;
}
if(strlen(m_szLocalIP) > 6 && strlen(m_szLocalIP) < 16)
strcpy(szPara, m_szLocalIP);
else
dwRet = GetHostIP(szPara);
dwRet = inet_addr(szPara);
if(dwRet == INADDR_NONE)
{
*plError = ERROR_INVALID_IP_ADDRESS;
goto INIT_EXIT;
}
BZERO(sSockAddr4Dest);
sSockAddr4Dest.sin_addr.S_un.S_addr = dwRet;
sSockAddr4Dest.sin_family = AF_INET;
if(!m_iPortListen)m_iPortListen = SGIP_PORT;
sSockAddr4Dest.sin_port = htons(m_iPortListen);
m_socket4SgipListen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, 0);
if(m_socket4SgipListen == INVALID_SOCKET)
{
*plError = ERROR_WS_INVALID_SOCKET;
goto INIT_EXIT;
}
dwRet = bind(m_socket4SgipListen, (struct sockaddr*)&sSockAddr4Dest, sizeof(sSockAddr4Dest));
if(dwRet != SOCKET_ERROR)
{
dwRet = listen(m_socket4SgipListen, SOMAXCONN);
if(dwRet != SOCKET_ERROR)
{
m_bIsEnableListen = true;
}
else
{
m_dwLastError4System = GetLastError();
m_bIsEnableListen = false;
}
}
else
{
m_dwLastError4System = GetLastError();
m_bIsEnableListen = false;
}
if(bStrSaveFile)strcpy(m_szSaveFile, W2A(bStrSaveFile));
if(lReListenInterTimeStepIs1MS)
{
m_dwReListenInterTime = lReListenInterTimeStepIs1MS;
}
BZERO(m_sSMBuffer);
m_lBufferIndex4MultiSM = -1;
LoadBuffer();
m_bIsInit = true;
//最后初始化m_cQueueEmpty为全满
for(i = 0; i < MAX_BUFFER_SIZE; i++)
{
#ifdef _DEBUG
ATLASSERT(m_cQueueEmpty.In(i));
#else
m_cQueueEmpty.In(i);
#endif
}
#ifdef _DEBUG
ATLASSERT(!m_cQueueEmpty.In(0));//队应该满了
#endif
//记录bstrDebugPath
if(bstrDebugPath)
{
char *pszDebugPath = W2A(bstrDebugPath);
UINT nDebugPathLen = strlen(pszDebugPath);
strcpy(this->m_szDebugPath, pszDebugPath);
if( nDebugPathLen && (m_szDebugPath[nDebugPathLen - 1] != '\\'))
{
strcat(m_szDebugPath, "\\");
}
}
DWORD dwThreadID;
m_hThreadAccept = CreateThread(0, 0, ThreadSGIPAccept, (void *)this, 0, &dwThreadID);
CloseHandle(m_hThreadAccept);
INIT_EXIT:
return S_OK;
}
//#define MAX_LENGTH_DELIVER (8 * 1024)
void SetReturnValue(VARIANT *pPara, long lPara)
{
if(pPara->vt & VT_BYREF)
{
switch(pPara->vt ^ VT_BYREF)
{
case VT_UI1:
case VT_I2:
case VT_I4:
*pPara->plVal = lPara;
break;
case VT_R4:
*pPara->pfltVal = (float)lPara;
break;
case VT_R8:
*pPara->pdblVal = lPara;
break;
case VT_BSTR:
char szValue[MAX_PATH];
itoa(lPara, szValue, 10);
*pPara->pbstrVal = A2BSTR(szValue);
break;
}
}
}
bool CheckTime(char * pszTime)
{
long lTime;
if(strlen(pszTime) == 12)
{
lTime = atol(pszTime + 2);
if(lTime >= 101000000 && lTime <= 1231235959)
{
lTime = atol(pszTime + 4);
if(lTime >= 1000000 && lTime <= 31235959)
{
lTime = atol(pszTime + 6);
if(lTime >= 0 && lTime <= 235959)
{
lTime = atol(pszTime + 8);
if(lTime >= 0 && lTime <= 5959)
{
lTime = atol(pszTime + 10);
if(lTime >= 0 && lTime <= 59)
{
return true;
}
}
}
}
}
}
return false;
}
DWORD WINAPI ThreadSGIPSend(LPVOID lpPara)
{
CPSgip *pcSgip = (CPSgip*)lpPara;
DWORD dwRet, dwIndex, dwCounter;
fd_set sFDS4Write;
FD_ZERO(&sFDS4Write);
pcSgip->m_bIsSendRun = true;
while(pcSgip->m_bIsEnableRun)// while(pcSgip->m_bIsEnableRun || pcSgip->GetWaitSendCount())
{
dwCounter = GetTickCount();
for(dwIndex = 0; dwIndex < MAX_BUFFER_SIZE; dwIndex++)
{
if(pcSgip->m_sSMBuffer[dwIndex].bFlag == FLAG_BUFFER_SENDED &&
(dwCounter - pcSgip->m_sSMBuffer[dwIndex].dwTickCount > ((ULONG)abs(pcSgip->m_lTimeout4Response) / 1000)))
{
if(pcSgip->m_lTimeout4Response > 0)
pcSgip->m_sSMBuffer[dwIndex].bFlag++;
else
{
//记录入文件
#ifdef REC_FILE
if(!pcSgip->m_cFileRecorder.Submit(pcSgip->m_szDebugPath, pcSgip->m_szCorpID, (BYTE*)&pcSgip->m_sSMBuffer[dwIndex].sSgipMsg, ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength), pcSgip->m_sSMBuffer[dwIndex].bFlag))
{
ATLTRACE("在ThreadCMPPSend中调用m_cFileRecorder.Submit()时,返回FALSE(1)\n");
}
#endif
pcSgip->m_sSMBuffer[dwIndex].bFlag = FLAG_BUFFER_VALID;
//这个空位入队
if(!pcSgip->m_cQueueEmpty.In(dwIndex))
{
ATLTRACE("在ThreadCMPPSend中pcCmpp->m_cQueueEmpty.In(dwIndex)时,返回FALSE(1)\n");
}
}
}
//if(pcSgip->m_sSMBuffer[dwIndex].bFlag == FLAG_BUFFER_READY)break;从队列中取,如下
if(pcSgip->m_sSMBuffer[dwIndex].bFlag >= FLAG_BUFFER_RETRY)
{
if(pcSgip->m_sSMBuffer[dwIndex].bFlag - FLAG_BUFFER_RETRY >= 3)
{
//记录入文件
#ifdef REC_FILE
if(!pcSgip->m_cFileRecorder.Submit(pcSgip->m_szDebugPath, pcSgip->m_szCorpID, (BYTE*)&pcSgip->m_sSMBuffer[dwIndex].sSgipMsg, ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength), pcSgip->m_sSMBuffer[dwIndex].bFlag))
{
ATLTRACE("在ThreadCMPPSend中调用m_cFileRecorder.Submit()时,返回FALSE(2)\n");
}
#endif
pcSgip->m_sSMBuffer[dwIndex].bFlag = FLAG_BUFFER_VALID;
//这个空位入队
if(!pcSgip->m_cQueueEmpty.In(dwIndex))
{
ATLTRACE("在ThreadCMPPSend中pcCmpp->m_cQueueEmpty.In(dwIndex)时,返回FALSE(2)\n");
}
}
else
{
pcSgip->m_sSMBuffer[dwIndex].bFlag++;
break;
}
}
}
if(!pcSgip->m_cQueueReady.Out((int*)&dwIndex))
{
if(pcSgip->m_lSendIntervalTime)Sleep(pcSgip->m_lSendIntervalTime / 1000);
continue;
}
//fill sgipmsg
SYSTEMTIME sSystemTime4Local;
GetLocalTime(&sSystemTime4Local);
dwRet = sSystemTime4Local.wMonth * 100000000 +
sSystemTime4Local.wDay * 1000000 +
sSystemTime4Local.wHour * 10000 +
sSystemTime4Local.wMinute * 100 +
sSystemTime4Local.wSecond;
pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.sMsgID.dwTime = htonl(dwRet);
pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength = htonl(sizeof(_SGIP_HEAD) + sizeof(_SGIP_SUBMIT) -
(long)(MAX_LEN_MOBILE_ID + 1) * MAX_DEST_USR - MAX_BUFFER_LEN_CONTENT - 1 +
(long)(MAX_LEN_MOBILE_ID + 1) * pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.bUserCount +
ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.dwMessageLength));
if(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.bUserCount < MAX_DEST_USR)
{
memcpy(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.szUserNumber +
(long)(MAX_LEN_MOBILE_ID + 1) * pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.bUserCount,
&pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.szCorpID,
ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.dwMessageLength) + 80);
//再把Reserved字段向前挤紧
memcpy(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.szUserNumber +
(long)(MAX_LEN_MOBILE_ID + 1) * pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.bUserCount +
ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.dwMessageLength) + 80 - 8,
pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.uMessageBody.sMessageSubmit.bReserve, 8);
}
#ifdef _DEBUG_FILE
char szFileName[MAX_PATH];
sprintf(szFileName, "d:\\temp\\test\\%08d.uni", ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.sMsgID.dwSequenceNO));
FILE *file4Debug = fopen(szFileName, "w");
fwrite(&pcSgip->m_sSMBuffer[dwIndex].sSgipMsg, ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength), 1, file4Debug);
fclose(file4Debug);
#else
#ifdef _DEBUG
char szFileName[MAX_PATH];
sprintf(szFileName, "%s%08d.uni", pcSgip->m_szDebugPath, ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.sMsgID.dwSequenceNO));
FILE *file4Debug = fopen(szFileName, "wb");
fwrite(&pcSgip->m_sSMBuffer[dwIndex].sSgipMsg, ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength), 1, file4Debug);
fclose(file4Debug);
#endif
while(pcSgip->m_bIsBinding);
FD_SET(pcSgip->m_sSocket4MT, &sFDS4Write);
dwRet = select(0, NULL, &sFDS4Write, NULL, NULL);
if(dwRet == SOCKET_ERROR)
{
pcSgip->m_dwLastError4System = GetLastError();
goto WAITSEND_EXIT;
}
if(dwRet == 0 || !FD_ISSET(pcSgip->m_sSocket4MT, &sFDS4Write))
{
goto WAITSEND_EXIT;
}
WSASetEvent(pcSgip->m_hEvent4Socket);
dwRet = send(pcSgip->m_sSocket4MT, (char *)&(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg), ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength), 0);
WSAResetEvent(pcSgip->m_hEvent4Socket);
if(dwRet == SOCKET_ERROR)
{
pcSgip->m_dwLastError4System = GetLastError();
goto WAITSEND_EXIT;
}
if(dwRet != ntohl(pcSgip->m_sSMBuffer[dwIndex].sSgipMsg.sMessageHead.dwCommandLength))
{
goto WAITSEND_EXIT;
}
pcSgip->m_dwSubmitNumber++;
#endif
pcSgip->m_sSMBuffer[dwIndex].dwTickCount = GetTickCount();
#ifdef _DEBUG_FILE
pcSgip->m_sSMBuffer[dwIndex].bFlag = FLAG_BUFFER_VALID;
#else
if(pcSgip->m_sSMBuffer[dwIndex].bFlag == FLAG_BUFFER_READY)
{
pcSgip->m_sSMBuffer[dwIndex].bFlag = FLAG_BUFFER_SENDED;
}
#endif
pcSgip->m_dwSendTime = GetTickCount() - dwCounter;
if(pcSgip->m_lSendIntervalTime)Sleep(pcSgip->m_lSendIntervalTime / 1000);
}
pcSgip->m_bIsSendRun = false;
return 0;
WAITSEND_EXIT:
pcSgip->m_bIsSendRun = false;
pcSgip->Terminate();
return 0;
}
DWORD WINAPI ThreadSGIPRecv(LPVOID lpPara)
{
CPSgip *pcSgip = (CPSgip*)lpPara;
DWORD dwRet;/*收到的数据包的总长(模拟对象)*/
DWORD dwRetMulti; //包含多个子数据包的包的长度
_SGIP sSgipMsg/*收到的单数据包内容(模拟对象)*/;
BYTE pRecvMulti[sizeof(_SGIP)]; //包含多个子数据包的数据包内容
timeval sTimeval4Timeout;
sTimeval4Timeout.tv_sec = pcSgip->m_lTimeout4Recv / 1000000;
sTimeval4Timeout.tv_usec = pcSgip->m_lTimeout4Recv % 1000000;
fd_set sFDS4Read;
FD_ZERO(&sFDS4Read);
pcSgip->m_bIsRecvRun = true;
while(pcSgip->m_bIsEnableRun)
{
while(pcSgip->m_bIsBinding);
FD_SET(pcSgip->m_sSocket4MT, &sFDS4Read);
dwRet = select(0, &sFDS4Read, NULL, NULL, &sTimeval4Timeout);
if(dwRet == SOCKET_ERROR)
{
pcSgip->m_dwLastError4System = GetLastError();
goto WAITRECV_EXIT;
}
if(dwRet == 0)
{
Sleep(pcSgip->m_lPauseTime4Recv / 1000);
continue;
}
WSASetEvent(pcSgip->m_hEvent4Socket);
//由下面的代码代替dwRet = recv(pcSgip->m_sSocket4MT, (char *)&sSgipMsg, sizeof(sSgipMsg), 0);
dwRetMulti = recv(pcSgip->m_sSocket4MT, (char *)pRecvMulti, sizeof(_SGIP), 0);
WSAResetEvent(pcSgip->m_hEvent4Socket);
if(dwRetMulti == SOCKET_ERROR || !dwRetMulti)
{
pcSgip->m_dwLastError4System = GetLastError();
goto WAITRECV_EXIT;
}
//下面用dwRetMulti和pRecvMulti[1024 * 2]对变量dwRet;和sSgipMsg进行模拟
DWORD dwCurMulti = 0;//当前的pRecvMulti的位置
while(dwCurMulti < dwRetMulti)
{
//模拟dwRet和sSgipMsg
dwRet = ntohl(((_SGIP_HEAD*)(pRecvMulti + dwCurMulti))->dwCommandLength);//dwRet
memcpy(&sSgipMsg, pRecvMulti + dwCurMulti, dwRet); //sSgipMsg
dwCurMulti += dwRet;
SYSTEMTIME sSystemTime4Local;
GetLocalTime(&sSystemTime4Local);
DWORD dwTime = sSystemTime4Local.wMonth * 100000000 +
sSystemTime4Local.wDay * 1000000 +
sSystemTime4Local.wHour * 10000 +
sSystemTime4Local.wMinute * 100 +
sSystemTime4Local.wSecond;
switch(ntohl(sSgipMsg.sMessageHead.dwCommandID))
{
case SGIP_SUBMIT_REP:
pcSgip->m_dwCurrentError4Protocol = sSgipMsg.uMessageBody.sMessageSubmitRep.bResult;
if(ntohl(sSgipMsg.sMessageHead.dwCommandLength) == sizeof(_SGIP_HEAD) + sizeof(_SGIP_SUBMIT_REP) &&
dwRet == sizeof(_SGIP_HEAD) + sizeof(_SGIP_SUBMIT_REP))
{
for(dwRet = 0; dwRet < MAX_BUFFER_SIZE; dwRet++)
{
if(pcSgip->m_sSMBuffer[dwRet].sSgipMsg.sMessageHead.sMsgID.dwSequenceNO == sSgipMsg.sMessageHead.sMsgID.dwSequenceNO)
{
pcSgip->m_dwResponseTime = GetTickCount() - pcSgip->m_sSMBuffer[dwRet].dwTickCount;
if(sSgipMsg.uMessageBody.sMessageSubmitRep.bResult)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -