⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timesrvdlg.cpp

📁 一个用于服务器与各客户端进行时间同步的源码.
💻 CPP
字号:
// TimeSrvDlg.cpp : implementation file
//

#include "stdafx.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#include <string.h>
#include "TimeSrv.h"
#include "TimeSrvDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define MYWM_NOTIFYICON WM_USER+1
NOTIFYICONDATA m_tnid;


const nPort = 8811;
int nRtn;

SOCKET sockSrv;
SOCKADDR_IN addrSrv;

#define		nClientNum 10
int	nSockStat[nClientNum];
SOCKET sockClt[nClientNum];

int nEndMovieNo;

CListBox *gLB;
void TraceInfo(const char *szFmt,...)
{
	char buf[512];
    va_list vlist;
    
    va_start(vlist, szFmt);
    vsprintf(buf, szFmt, vlist);
    va_end(vlist);
	
	gLB->InsertString(0,buf);
	if (gLB->GetCount() >= 100)
		gLB->DeleteString(100);
}

void TrimStr(char *ptr,int nSize)
{
	char strTemp[100],*cTemp;
	memset(strTemp,0,100);
	cTemp = strTemp;
	for (int i = 0  ; i < nSize ; i ++ ) 
	{
		if ( ptr[i] == 0x0d  || ptr[i] == 0x0a )	// 13 or 10
			break;
		else if ( ptr[i] == 0x09  || ptr[i] == 0x20 )	//tab or space
			continue;
		else *cTemp ++ = ptr[i];
	}
	strcpy(ptr, strTemp);
}

bool bLoad;
void AppBegin()
{
	bLoad = true;
	WSADATA wsaData;
	if (0 != WSAStartup(MAKEWORD(2,1),&wsaData))
	{
		bLoad = false;
		AfxMessageBox("WSAStartup 错误");
		exit(0);
	}
	CoInitialize(NULL);
}

void AppExit()
{
	CoUninitialize();
	::Shell_NotifyIcon(NIM_DELETE,&m_tnid);
	if (bLoad)
	{
		WSACleanup();
		TRACE(_T("AppExit and WSACleanup!\n"));
		exit(0);
	}
}

CString IntToStr(int nValue)
{
	char sValue[10];
	memset(sValue,0,10);
	itoa(nValue,sValue,10);
	CString sRtn = sValue;
	return sRtn;
}

DWORD WINAPI Solve_Thread(LPVOID pIndex)
{
	int *ptmp = (int *)pIndex;	
	int nCurIdx = *ptmp;

	char *pTmp;
	char sMsg[100],sMsgRtn[100],sMsgTmp[100];

	char cTemp0[1],cTemp1[1];
	CString sValue;
	CString sRetrunInfo;
	
	int nLoop = 0;
	memset(sMsgRtn,0,100);
	bool bGoon = true;
	int nRtn;
	while(1)
	{	
		nLoop++;
		if (nLoop > 1000)
			goto RTN;
		//TraceInfo("Solve_Thread; enter into while\n");
		cTemp0[0] = 0;
		if (recv(sockClt[nCurIdx],cTemp0,sizeof(char),0) < 0)
		{
			TraceInfo("Solve_Thread; recv1:errno:%d\n",WSAGetLastError());
			goto RTN;
		}
		//TraceInfo("Solve_Thread; recv cTemp0 is %c\n",cTemp0[0]);
		if (cTemp0[0] != '^')
		{
			continue;
		}
		cTemp1[0] = 0;
		if (recv(sockClt[nCurIdx],cTemp1,sizeof(char),0) < 0)//MSG_PARTIAL
		{
			TraceInfo("Solve_Thread; recv2:errno:%d\n",WSAGetLastError());
			goto RTN;
		}
		//TraceInfo("Solve_Thread; recv cTemp1 is %c\n",cTemp1[0]);
		if (cTemp1[0] != '^')
		{
			continue;
		}

		memset(sMsg, 0, 100); 
		if (recv(sockClt[nCurIdx],sMsg,98 * sizeof(char),0) < 98)//MSG_WAITALL
		{
			TraceInfo("Solve_Thread; recv3:errno:%d\n",WSAGetLastError());
			goto RTN;
		}
		//TraceInfo("Solve_Thread; recv sMsg is %s\n",sMsg);

		memset(sMsgTmp,0,100);
		memcpy(sMsgTmp,sMsg,11);		

		if (strcmp(sMsgTmp,"wantyoutime") == 0 && sMsg[96] == '*' && sMsg[97] == '*')
		{
			memset(sMsgRtn,32,100);

			CTime	dtNow = CTime::GetCurrentTime(); 
			sValue = dtNow.Format( "=%Y-%m-%d#%H:%M:%S=" );//=2002-10-18#20:40:02=

			sMsgRtn[0] = cTemp0[0];
			sMsgRtn[1] = cTemp1[0];
			sMsgRtn[98] = '*';
			sMsgRtn[99] = '*';

			pTmp = sMsgRtn + 2;
			memcpy(pTmp,LPCTSTR(sValue),sValue.GetLength());

			sValue = dtNow.Format( "Now is %Y-%m-%d %H:%M:%S" );
			TraceInfo("%s\n",LPCTSTR(sValue));
		}
		break;
	}

RTN:
	nRtn = send(sockClt[nCurIdx],sMsgRtn,100,0);
	nSockStat[nCurIdx] = -1;
	closesocket(sockClt[nCurIdx]);
	sockClt[nCurIdx] = INVALID_SOCKET;
	return 1;
}

DWORD WINAPI Listen_Thread(LPVOID pId)
{
	int nCurIdx = -1;

	while(1)
	{
		nCurIdx = -1;
		for (int i = 0; i < nClientNum; i++)
		{
			if (nSockStat[i] == -1)
			{
				nCurIdx = i;
				nSockStat[i] = i;
				break;
			}
		}
		if (nCurIdx == -1)
		{
			::Sleep(1000);
			continue;
		}

		//TraceInfo("Listen_Thread:: select %d idx\n",nCurIdx);
		struct sockaddr_in address;
		int address_len = sizeof(address);
		//sockClt[nCurIdx] = accept(sockSrv,NULL, NULL);
		sockClt[nCurIdx] = accept(sockSrv,(struct sockaddr *)&address, &address_len);

		if(sockClt[nCurIdx] == INVALID_SOCKET)
	    {
			nSockStat[nCurIdx] = -1;
			TraceInfo("Listen_Thread:: accept; errno:%d\n",WSAGetLastError());
	        continue;
	    }
		else TraceInfo("Want Time From %s\n",inet_ntoa(address.sin_addr));//*/
		/*else TraceInfo("Listen_Thread:: accept; from %d.%d.%d.%d",
						address.sin_addr.S_un.S_un_b.s_b1,
						address.sin_addr.S_un.S_un_b.s_b2,
						address.sin_addr.S_un.S_un_b.s_b3,
						address.sin_addr.S_un.S_un_b.s_b4);//*/
		
	

		HANDLE hRtn = ::CreateThread(NULL,0,Solve_Thread,&nSockStat[nCurIdx],0,NULL);
		if (hRtn == NULL)
		{
			nSockStat[nCurIdx] = -1;
			closesocket(sockClt[nCurIdx]);
			sockClt[nCurIdx] = INVALID_SOCKET;
			TraceInfo("Listen_Thread:: CreateThread; errno:%d\n",WSAGetLastError());
		}
		//else TraceInfo("Listen_Thread:: CreateThread; OK");
	}
	return 1;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTimeSrvDlg dialog

CTimeSrvDlg::CTimeSrvDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTimeSrvDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTimeSrvDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTimeSrvDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTimeSrvDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTimeSrvDlg, CDialog)
	//{{AFX_MSG_MAP(CTimeSrvDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BtnClose, OnBtnClose)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTimeSrvDlg message handlers

BOOL CTimeSrvDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	AppBegin();
	gLB = (CListBox *)GetDlgItem(IDC_LISTINFO);

	StartTimeSrv();

	m_tnid.cbSize=sizeof(NOTIFYICONDATA); 
	m_tnid.hWnd=this->m_hWnd; 
	m_tnid.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP; 
	m_tnid.uCallbackMessage=MYWM_NOTIFYICON; 
	CString szToolTip; 
	szToolTip=_T("时间同步服务器"); 
	_tcscpy(m_tnid.szTip, szToolTip); 
	m_tnid.uID=IDD_TIMESRV_DIALOG; 
	m_tnid.hIcon=m_hIcon; 
	::Shell_NotifyIcon(NIM_ADD,&m_tnid);
	
	AfxGetMainWnd()->PostMessage(WM_SYSCOMMAND,SC_MINIMIZE,0);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTimeSrvDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTimeSrvDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CTimeSrvDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTimeSrvDlg::OnBtnClose() 
{
	// TODO: Add your control notification handler code here
	AppExit();
}

void CTimeSrvDlg::StartTimeSrv()
{
	for (int i = 0; i < nClientNum; i++)
	{
		nSockStat[i] = -1;
		sockClt[i] = INVALID_SOCKET;
	}

	sockSrv = socket(AF_INET,SOCK_STREAM,0);
	if (sockSrv == INVALID_SOCKET)
	{
		TraceInfo("socket 错误,errno:%d\n",WSAGetLastError());
		AppExit();
	}
	else TraceInfo("socket OK");

	const char ifreuse = 1;
	nRtn = setsockopt(sockSrv,SOL_SOCKET,SO_REUSEADDR,&ifreuse,sizeof(int));
	if(nRtn < 0)
	{
		TraceInfo("setsockopt 错误,errno:%d\n",WSAGetLastError());
		AppExit();
	}
	else TraceInfo("setsockopt OK");

	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(nPort);
	addrSrv.sin_addr.s_addr = INADDR_ANY;	
	nRtn = bind(sockSrv,(struct sockaddr*)&addrSrv,sizeof(struct sockaddr));
	if (0 != nRtn)
	{
		TraceInfo("bind 错误,errno:%d\n",WSAGetLastError());
		AppExit();
	}
	else TraceInfo("bind OK");

	nRtn = listen(sockSrv,100);
	if (0 != nRtn)
	{
		TraceInfo("listen 错误,errno:%d\n",WSAGetLastError());
		AppExit();
	}
	else TraceInfo("listen OK");

	::CreateThread(NULL,0,Listen_Thread,NULL,0,NULL);
}

LRESULT CTimeSrvDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	switch(message)
	{ 
		case MYWM_NOTIFYICON: if(lParam == WM_LBUTTONDBLCLK || lParam == WM_RBUTTONDOWN) 
								  ShowWindow(SW_SHOW); 
			break;
		case WM_SYSCOMMAND:   if(wParam == SC_MINIMIZE)
							  {
								  ShowWindow(SW_HIDE);
								  return 0;
							  }
			break;
	} 
	return CDialog::WindowProc(message, wParam, lParam);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -