📄 ntpsock.cpp
字号:
//Transfer all the useful info into the response structure
response.m_nStratum = nfp.m_Basic.m_Stratum;
response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
//st = SYSTEMTIME(response.m_OriginateTime);
//printf("st 消息发送时间,%04d-%02d-%02d %02d:%02d:%02d:%03d \n",
//st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
//st = SYSTEMTIME(response.m_OriginateTime);
//printf("st 消息接受时间,%04d-%02d-%02d %02d:%02d:%02d:%03d \n",
//st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
//st = SYSTEMTIME(response.m_TransmitTime);
//printf("st 消息传送时间,%04d-%02d-%02d %02d:%02d:%02d:%03d \n",
//st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
//st = SYSTEMTIME(response.m_DestinationTime);
//printf("st 消息到达时间,%04d-%02d-%02d %02d:%02d:%02d:%03d \n",
//st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime);
response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2;
RepairSystemTime(&response);
}
/// anyCast 获取服务器地址信息
else if( mIsAnyCast)
{
char *lServerAddr = inet_ntoa(fromAddr.sin_addr);
if( lServerAddr != NULL )
{
memset(mServerAddr,0,sizeof(mServerAddr));
strcpy(mServerAddr,lServerAddr);
mIsAnyCast = false;
mIsGetServerAddr = true;
if( pLog )
{
char logMsg[200];
sprintf(logMsg,"成功获取服务器地址%s ",mServerAddr);
pLog->AddMsgIntoTail(logMsg);
}
mIsAnyCast = false;
mIsGetServerAddr = true;
}
}
/// 获取网络数据传输延时信息
else if( mIsMultiCast && !GetIsTakeNetDelay())
{
//Transfer all the useful info into the response structure
response.m_nStratum = nfp.m_Basic.m_Stratum;
response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
response.m_RoundTripDelay = (response.m_DestinationTime - response.m_OriginateTime) - (response.m_ReceiveTime - response.m_TransmitTime);
response.m_LocalClockOffset = ((response.m_ReceiveTime - response.m_OriginateTime) + (response.m_TransmitTime - response.m_DestinationTime)) / 2;
mNetDelay = response.m_RoundTripDelay;
mIsGetNetDelay = true;
printf(" 成功获取网络延时 \n" );
}
}
/// 开始接受服务器多播消息
if( mode == 5 )
{
if( GetIsMultiCast() && GetIsTakeNetDelay())
{
//Transfer all the useful info into the response structure
response.m_nStratum = nfp.m_Basic.m_Stratum;
response.m_nLeapIndicator = (nfp.m_Basic.m_LiVnMode & 0xC0) >> 6;
//mNetDelay
response.m_OriginateTime = nfp.m_Basic.m_OriginateTimestamp;
response.m_ReceiveTime = nfp.m_Basic.m_ReceiveTimestamp;
response.m_TransmitTime = nfp.m_Basic.m_TransmitTimestamp;
response.m_RoundTripDelay = mNetDelay;
response.m_LocalClockOffset = response.m_TransmitTime - response.m_DestinationTime + mNetDelay ;
RepairSystemTime(&response);
}
else if(GetIsAnyCast())
{
char *lServerAddr = inet_ntoa(fromAddr.sin_addr);
if( lServerAddr != NULL )
{
memset(mServerAddr,0,sizeof(mServerAddr));
strcpy(mServerAddr,lServerAddr);
mIsAnyCast = false;
mIsGetServerAddr = true;
if( pLog )
{
char logMsg[200];
sprintf(logMsg,"成功获取服务器地址%s ",mServerAddr);
pLog->AddMsgIntoTail(logMsg);
}
mIsAnyCast = false;
mIsGetServerAddr = true;
}
}
}
}
#ifdef __Win32__
Sleep(1);
#else
usleep(1*1000);
#endif
}
}
Bool8 CConnectionPeer::StartDataRecvThread()
{
mIsGetNetDelay = false;
mIsGetServerAddr = false;
mNetDelay = 0;
if(!mPeerSocket.Create())
return false;
if(mPeerSocket.ReuseAddr())
return false;
if(mPeerSocket.Bind(mLocalPort) != 0)
return false;
//if(mPeerSocket.SetIPLoop() != 0)
// return false;
if( mIsAnyCast || mIsMultiCast)
mPeerSocket.SetSockMulticast(mMultiCastAddr,true);
mPeerSocket.SetLoopBack(0); //(1);
#ifdef __Win32__
DWORD threadId;
mRecvThreadHandle = CreateThread(NULL,0,_StartDataRecvThread,this,0,&threadId);
if(mRecvThreadHandle == NULL)
return false;
#endif
#ifdef __REDHATLINUX__
int ret = pthread_create(&mRecvThreadHandle,NULL,_StartDataRecvThread,(void *)this);
if(ret)
return false;
#endif
return true;
}
Bool8 CConnectionPeer::TerminateDataRecvThread()
{
#ifdef __Win32__
if(mRecvThreadHandle != NULL)
{
mPeerSocket.Close();
TerminateThread(mRecvThreadHandle,0);
CloseHandle(mRecvThreadHandle);
mRecvThreadHandle = NULL;
}
#endif
#ifdef __REDHATLINUX__
#endif
return true;
}
void CConnectionPeer::DataSendThread()
{
while(1)
{
if(GetIsMultiCast())
{
if(GetIsTakeNetDelay())
{
printf("停止发送请求数据 \n");
break;
}
SendTimeSynData();
}
else if (GetIsAnyCast())
{
SendAnyMultiCastSynData();
}
else
SendTimeSynData();
sleep(mUniCastPeriod);
}
if(GetIsMultiCast() )
{
if( pLog && GetIsTakeNetDelay())
pLog->AddMsgIntoTail("成功获取网络延时, 停止单播数据发送");
}
pthread_exit(0);
}
Bool8 CConnectionPeer::StartDataSendThread()
{
#ifdef __Win32__
DWORD threadId;
mSendThreadHandle = CreateThread(NULL,0,_StartDataSendThread,this,0,&threadId);
if(mRecvThreadHandle == NULL)
return false;
#endif
#ifdef __REDHATLINUX__
int ret = pthread_create(&mSendThreadHandle,NULL,_StartDataSendThread,(void *)this);
if(ret)
return false;
#endif
return true;
}
Bool8 CConnectionPeer::TerminateDataSendThread()
{
#ifdef __Win32__
if(mRecvThreadHandle != NULL)
{
//mPeerSocket.Close();
TerminateThread(mSendThreadHandle,0);
CloseHandle(mSendThreadHandle);
mSendThreadHandle = NULL;
}
#endif
#ifdef __REDHATLINUX__
#endif
return true;
}
int CConnectionPeer::SendAnyMultiCastSynData()
{
if( mMultiCastAddr == NULL)
return OS_HasError;
struct sockaddr_in toAddr;
memset(&toAddr,0,sizeof(toAddr));
toAddr.sin_port = htons(mLocalPort);
toAddr.sin_family = AF_INET;
toAddr.sin_addr.s_addr = inet_addr(mMultiCastAddr);
NtpBasicInfo nbi;
memset(&nbi,0,sizeof(nbi));
int nSendSize = sizeof(NtpBasicInfo);
memset(&nbi,0,sizeof(nSendSize));
nbi.m_LiVnMode = 35; //Encoded representation which represents NTP Client Request & NTP version 3.0
nbi.m_TransmitTimestamp = CNtpTime::GetCurrentTime();
//Send off the NtpBasicInfo packet
if (!mPeerSocket.Send((char *)&nbi, nSendSize, &toAddr))
return OS_HasError;
if(pLog)
pLog->AddMsgIntoTail("客户端成功发送多播请求消息(AnyCast)");
return OS_NoError;
}
int CConnectionPeer::SendMultiCastSynData()
{
if( mMultiCastAddr == NULL)
return OS_HasError;
struct sockaddr_in toAddr;
memset(&toAddr,0,sizeof(toAddr));
toAddr.sin_port = htons(mLocalPort);
toAddr.sin_family = AF_INET;
toAddr.sin_addr.s_addr = inet_addr(mMultiCastAddr);
NtpBasicInfo nbi;
memset(&nbi,0,sizeof(nbi));
int nSendSize = sizeof(NtpBasicInfo);
//ZeroMemory(&nbi, nSendSize);
memset(&nbi,0,nSendSize);
nbi.m_LiVnMode = 37; //Encoded representation which represents NTP Client Request & NTP version 3.0
nbi.m_TransmitTimestamp = CNtpTime::GetCurrentTime();
//Send off the NtpBasicInfo packet
if (!mPeerSocket.Send((char *)&nbi, nSendSize, &toAddr))
return OS_HasError;
if(pLog)
pLog->AddMsgIntoTail("服务器成功发送多播消息(MultiCast)");
return OS_NoError;
}
void CConnectionPeer::MultiCastSendThread()
{
while(1)
{
SendMultiCastSynData();
if(mMultiCastPeriod <= 0)
{
#ifdef __Win32__
Sleep(1000);
#else
usleep(1000*1000);
#endif
}
else
{
#ifdef __Win32__
Sleep(mMultiCastPeriod);
#else
usleep(mMultiCastPeriod*1000);
#endif
}
}
}
Bool8 CConnectionPeer::StartMultiCastSendThread()
{
if(!mIsMultiCast)
return false;
#ifdef __Win32__
DWORD threadId;
mMultiCastThreadHandle = CreateThread(NULL,0,_StartMultiCastSendThread,this,0,&threadId);
if(mMultiCastThreadHandle == NULL)
return false;
#endif
#ifdef __REDHATLINUX__
int ret;
ret = pthread_create(&mMultiCastThreadHandle,NULL,_StartMultiCastSendThread,(void *)this);
if(ret)
return false;
#endif
return true;
}
Bool8 CConnectionPeer::TerminateMultiCastSendThread()
{
#ifdef __Win32__
if(mMultiCastThreadHandle != NULL)
{
TerminateThread(mMultiCastThreadHandle,0);
CloseHandle(mMultiCastThreadHandle);
mMultiCastThreadHandle = NULL;
}
#endif
#ifdef __RETHATLINUX__
#endif
return true;
}
void CConnectionPeer::SetMultiCastPeriod(unsigned int multicastPeriod)
{
mMultiCastPeriod = multicastPeriod;
}
void CConnectionPeer::SetServerPort(unsigned short port)
{
mServerPort = port;
}
void CConnectionPeer::SetServerAddr(char *addr)
{
if( addr == NULL)
return;
memset(mServerAddr,0,sizeof(mServerAddr));
if( strlen(addr) > 16)
return;
strcpy(mServerAddr,addr);
}
void CConnectionPeer::SetMulticastAddr(char *addr)
{
if( addr == NULL)
return;
memset(mMultiCastAddr,0,sizeof(mMultiCastAddr));
if( strlen(addr) > 16)
return;
strcpy(mMultiCastAddr,addr);
}
void CConnectionPeer::SetLocalPort(unsigned short port)
{
mLocalPort = port;
}
void CConnectionPeer::SetAnyCast( bool isTrue)
{
mIsAnyCast = isTrue;
}
void CConnectionPeer::SetMultiCast( bool isTrue)
{
mIsMultiCast = isTrue;
}
#ifdef __Win32__
Bool8 CConnectionPeer::GetSetTimePriviledge()
{
BOOL bOpenToken = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY, &m_hToken);
m_bTakenPriviledge = false;
if (!bOpenToken)
{
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
//Must be running on 95 or 98 not NT. In that case just ignore the error
SetLastError(ERROR_SUCCESS);
return false;
}
TRACE(_T("Failed to get Adjust priviledge token\n"));
return false;
}
ZeroMemory(&m_TokenPriv, sizeof(TOKEN_PRIVILEGES));
if (!LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &m_TokenPriv.Privileges[0].Luid))
{
TRACE(_T("Failed in callup to lookup priviledge\n"));
return FALSE;
}
m_TokenPriv.PrivilegeCount = 1;
m_TokenPriv.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
m_bTakenPriviledge = TRUE;
Bool8 bSuccess = AdjustTokenPrivileges(m_hToken, false, &m_TokenPriv, 0, NULL, 0);
if (!bSuccess)
TRACE(_T("Failed to adjust SetTime priviledge\n"));
return bSuccess;
}
void CConnectionPeer::CancelSetTimePriviledge()
{
if (m_bTakenPriviledge)
{
m_TokenPriv.Privileges[0].Attributes &= (~SE_PRIVILEGE_ENABLED);
if (!AdjustTokenPrivileges(m_hToken, false, &m_TokenPriv, 0, NULL, 0))
TRACE(_T("Failed to reset SetTime priviledge\n"));
}
}
#endif
Bool8 CConnectionPeer::RepairSystemTime(NtpServerResponse *resp)
{
char logBuffer[500];
#ifdef __Win32__
memset(logBuffer,0,sizeof(logBuffer));
if(GetSetTimePriviledge())
{
CNtpTime newTime(CNtpTime::GetCurrentTime() + resp->m_LocalClockOffset);
SYSTEMTIME st = SYSTEMTIME(newTime);
// if (SetSystemTime(&SYSTEMTIME(newTime)))
if (SetSystemTime(&st))
{
if(pLog)
{
sprintf(logBuffer,"系统时间成功修改,当前UTC时间是%04d-%02d-%02d %02d:%02d:%02d:%03d",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
pLog->AddMsgIntoTail(logBuffer);
}
}
else
{
if(pLog)
pLog->AddMsgIntoTail("Failed to set the local time");
}
CancelSetTimePriviledge();
}
else
{
if(pLog)
{
strcpy(logBuffer,"本应用无权修改系统时间,系统时间修改失败");
pLog->AddMsgIntoTail(logBuffer);
}
}
#endif
#ifdef __REDHATLINUX__
CNtpTime newTime(CNtpTime::GetCurrentTime() + resp->m_LocalClockOffset);
SYSTEMTIME st = SYSTEMTIME(newTime);
//printf("\n 设置前系统时间,当前UTC时间是%04d-%02d-%02d %02d:%02d:%02d:%03d \n",
// st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
if (SetSystemTime(st))
{
if(pLog)
{
sprintf(logBuffer,"系统时间成功修改,当前UTC时间是%04d-%02d-%02d %02d:%02d:%02d:%03d",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
pLog->AddMsgIntoTail(logBuffer);
}
}
else
{
if(pLog)
pLog->AddMsgIntoTail("Failed to set the local time");
}
#endif
return true;
}
Bool8 CConnectionPeer::GetIsUniCast()
{
return (!(mIsMultiCast || mIsAnyCast));
}
Bool8 CConnectionPeer::GetIsMultiCast()
{
return mIsMultiCast;
}
Bool8 CConnectionPeer::GetIsAnyCast()
{
return mIsAnyCast;
}
Bool8 CConnectionPeer::GetIsTakeNetDelay()
{
return mIsGetNetDelay;
}
Bool8 CConnectionPeer::GetIsTackServerAddr()
{
return mIsGetServerAddr;
}
void CConnectionPeer::SetUniCastPeriod(unsigned int unicastPeriod)
{
if(unicastPeriod > 0)
mUniCastPeriod = unicastPeriod;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -