Files
envi-code/SourceCode/Code2026/EarthWormMain/WaitEventDlg.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

372 lines
8.5 KiB
C++

#include "stdafx.h"
#include "WaitEventDlg.h"
#include "CheckLock.h"
#include <winsock.h>
#ifndef WM_CLIENTMSG
#define WM_CLIENTMSG (WM_USER+0x1002)
#endif
static HANDLE g_hSend = NULL;
static HANDLE g_hClient = NULL;
typedef struct ClientMsg
{
SOCKET sock;
char szMsg[MAX_PATH];
}SOCKMSG;
typedef enum ClientEvent
{
kLogin = 1, //登录
kLogout = 2, //退出
kPassok = 3, //许可
kAccessError = 4, //超出节点数
kAskforLogin = 5, //请求登录
kProError = 6, //请求登陆产品不对
kHeartbeat = 7, //心跳判断有效性
}CLIENTEVENT;
IMPLEMENT_DYNAMIC(CWaitEventDlg, CDialog)
CWaitEventDlg::CWaitEventDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWaitEventDlg::IDD, pParent)
{
m_pCheckLock = NULL;
m_bCheckSrvOk = false;
}
CWaitEventDlg::~CWaitEventDlg()
{
}
void CWaitEventDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_BUSYPROGRESSC, m_ctlBusy);
}
BEGIN_MESSAGE_MAP(CWaitEventDlg, CDialog)
ON_BN_CLICKED(IDCANCEL, &CWaitEventDlg::OnBnClickedCancel)
ON_WM_CLOSE()
ON_WM_TIMER()
ON_WM_DESTROY()
ON_MESSAGE(WM_CLIENTMSG,&CWaitEventDlg::OnClientMsg)
END_MESSAGE_MAP()
void CWaitEventDlg::SetCheckLock(CCheckLock* pCheckLock)
{
m_pCheckLock = pCheckLock;
}
DWORD ClientSockThread(LPVOID pParameter)
{
if (pParameter == NULL)
return 0;
ThreadParam* pThreadParam = (ThreadParam*)pParameter;
WORD sockVersion = MAKEWORD(1,1);
WSADATA wsaData;
//The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process
WSAStartup(sockVersion, &wsaData);
//Get the information about client entity
SOCKET sclient = (SOCKET)pThreadParam->pCheckLock->m_theSocket;
int nRes = 0; //Return val
char szBuf[MAX_PATH]; //used to send the validated data to client
//int nNetTimeout = 1000;//1秒,
//setsockopt(sclient,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
while(TRUE)
{
memset(szBuf,0,MAX_PATH); //reset
//Get the data form client
nRes = recv(sclient,szBuf,MAX_PATH,0);
/*if ( !::IsWindow(pThreadParam->hWnd) )
{
break;
}*/
if (nRes == -1 || pThreadParam->pCheckLock->m_bAutocadExit)
break;
//int nNetTimeout = 1000;//1秒,
//setsockopt(sclient,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
//post message to mainframewnd;
if (strlen(szBuf) > 0)
{
ClientMsg* pMsg = new ClientMsg;
pMsg->sock = sclient;
strcpy(pMsg->szMsg,szBuf);
if ( ::IsWindow(pThreadParam->hWnd ) )
{
::SendMessage(pThreadParam->hWnd,WM_CLIENTMSG,0,(LPARAM)pMsg);
}
else
{
break;
}
//如果是心跳验证
if (strstr(szBuf,"evn=7") != NULL)
{
//发向服务端
nRes = send(sclient, szBuf, MAX_PATH, 0);//固定长度
if (nRes == SOCKET_ERROR)
{
nRes = send(sclient, szBuf, MAX_PATH, 0);//固定长度
}
}
}
}
return 0;
}
UINT SendMessage2LockServerThread(LPVOID pParameter)
{
if (pParameter == NULL)
return 0;
ThreadParam* pThreadParam = (ThreadParam*)pParameter;
CCheckLock* pCheckLock = pThreadParam->pCheckLock;
ProductInfo* pProInfo = &pCheckLock->m_proInfo;
//1.网络通讯
WORD nVersion; //used to store the socket version
WSADATA wsaData; //used to store info about socket
sockaddr_in serverInfo; //used to specify a local or remote endpoint address to which to connect a socket
int nRes; //used to store return value
//get the version of socket
nVersion = MAKEWORD(1,1);
begin_pos:
//The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process
nRes = WSAStartup(nVersion,(LPWSADATA)&wsaData);
//here we are creating the socket
pCheckLock->m_theSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(pCheckLock->m_theSocket == SOCKET_ERROR)
{
WSACleanup();
goto begin_pos;
}
//Fill in the sockaddr_in struct
serverInfo.sin_family = PF_INET;
serverInfo.sin_addr.s_addr = inet_addr(pProInfo->szServer);
//随机取注册中的端口号
srand( (unsigned)time(NULL) );
int nindex = rand() % 5;
serverInfo.sin_port = htons( pProInfo->nPort[nindex] );
//Connect to the socket we just created
nRes = connect(pCheckLock->m_theSocket,(LPSOCKADDR)&serverInfo, sizeof(serverInfo));
if(nRes == SOCKET_ERROR)
{
WSACleanup();
goto begin_pos;
}
//获取本地ip 地址
char szHost[64],sHostIP[64];
gethostname(szHost,64);
struct hostent* phe = gethostbyname(szHost);
if (phe != NULL)
{
struct in_addr addr;
memcpy(&addr,phe->h_addr_list[0],sizeof(struct in_addr));
sprintf(sHostIP,"%s-%s",inet_ntoa(addr),szHost);
}
else
{
sprintf(sHostIP,"%s",szHost);
}
static char szBuf[MAX_PATH];
memset(szBuf,0,MAX_PATH);
#if (ARX <=15)
sprintf(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2000;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=16)
sprintf(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2004;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=17)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2008;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=18)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2010;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=19)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2013;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=20)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2016;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#elif (ARX<=21)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2019;",sHostIP,pProInfo->szProCode,pProInfo->dwVersion,kLogin);
#endif
//strcpy(szBuf,"ip=10.0.2.15;pro=GBMEP;ver=2012;evn=1;cad=AutoCAD2008;");
//CString sBuf = szBuf;
//acedGetAcadFrame()->SetWindowText(sBuf);
//int nNetTimeout = 1000;//1秒,
//setsockopt(pCheckLock->m_theSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
send_pos:
//Send the data to the server
nRes = send(pCheckLock->m_theSocket, szBuf, MAX_PATH, 0);//固定长度
if(nRes == SOCKET_ERROR)
{
goto send_pos;
}
//等待服务端的响应
DWORD ThreadId;
g_hClient = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ClientSockThread,(LPVOID)pParameter,0,&ThreadId);
return 0;
}
BOOL CWaitEventDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBusy.SetNumSteps(20);
m_ctlBusy.SetSpeed(250);
m_ctlBusy.SetRange(-100, 100);
m_ctlBusy.SetBusyType(BPC_BUSY_LTR);
m_ctlBusy.Start();
SetTimer(1000, 1000, NULL);
m_threadParam.hWnd = m_hWnd;
m_threadParam.pCheckLock = m_pCheckLock;
//等待服务端的响应
DWORD ThreadId;
g_hSend = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SendMessage2LockServerThread,(LPVOID)&m_threadParam,0,&ThreadId);
return TRUE;
}
void CWaitEventDlg::OnBnClickedCancel()
{
if (g_hSend)
{
if (::TerminateThread(g_hSend, 0))
g_hSend = NULL;
}
if (g_hClient)
{
if (::TerminateThread(g_hClient, 0))
g_hClient = NULL;
}
OnCancel();
}
void CWaitEventDlg::OnClose()
{
}
void CWaitEventDlg::OnTimer(UINT_PTR nIDEvent)
{
int nLower, nUpper;
int nCurPos = m_ctlBusy.GetCurPos();
m_ctlBusy.GetRange(nLower, nUpper);
if ( nCurPos >= nUpper-nLower)
m_ctlBusy.SetCurPos(0);
else
m_ctlBusy.StepIt();
CDialog::OnTimer(nIDEvent);
}
void CWaitEventDlg::OnDestroy()
{
m_ctlBusy.End();
KillTimer(1000);
CDialog::OnDestroy();
}
void ParaseScript(LPCTSTR pszMsg,CStringArray& arEves)
{
//ip=;pro=;ver=;evn=;cad=;
int nindex = 0,npos = 0;
CString sText = pszMsg;
CString sTemp;
nindex = sText.Find(_T("="));
if (nindex != -1)
{
npos = sText.Find(_T(";"));
if (npos != -1)
{
sTemp = sText.Mid(nindex + 1,npos - nindex - 1);
arEves.Add(sTemp);
if (npos + 1 < sText.GetLength() )
{
sTemp = sText.Mid(npos + 1);
if (!sTemp.IsEmpty())
{
ParaseScript(sTemp,arEves);
}
}
}
}
}
LRESULT CWaitEventDlg::OnClientMsg(WPARAM wp,LPARAM lp)
{
ClientMsg* pMsg = (ClientMsg*)lp;
if (pMsg != NULL)
{
//解释 szBuf 脚本格式 ip=;pro=;ver=;evn=;cad=; //登录者请求事件
CStringArray arEves;
CString sMsg = pMsg->szMsg;
ParaseScript(sMsg,arEves);
if (arEves.GetSize() >= 5)
{
ClientEvent nEve = (ClientEvent)_ttoi(arEves.GetAt(3));
switch(nEve)
{
case kPassok:
{
//AfxMessageBox(_T("服务端允许登录!!"));
m_bCheckSrvOk = true;
break;
}
case kAccessError:
{
AfxMessageBox(_T("网络锁许可节点数已经用完! 服务端不允许登录!"));
break;
}
case kProError:
{
AfxMessageBox(_T("网络锁中未注册该产品! 服务端不允许登录!"));
break;
}
case kHeartbeat:
{
//
break;
}
default:
break;
}
}
}
delete pMsg;
EndDialog(IDOK);
return 0;
}