您的位置:逆风者 VC++ 正文
 添加时间:2007-09-01 原文发表:2007-08-31 人气:71 来源:vckbase.com

本文章共2307字,分2页,当前第1页,快速翻页:
 

利用RFC868协议编写网络对时程序


作者:四川绵阳电业局 缪元虎

下载源代码
逆@风@者


一、网络授时服务

  网络授时服务是在网络上设置一些时间服务器,用户通过Internet访问这些时间服务器就可同步本地计算机时钟的服务。网络授时服务有三个协议,分别是Network Time Protocol (RFC-1305),Daytime Protocol (RFC-867),Time Protocol (RFC-868)。

有关这些协议的详细信息,可参考以下网站:

http://www.boulder.nist.gov/timefreq/service/its.htm

http://www.faqs.org/rfcs/rfc867.html

http://www.faqs.org/rfcs/rfc1305.html

http://www.faqs.org/rfcs/rfc868.html

我的程序中列出的时间服务器列表,主要来自:

http://www.boulder.nist.gov/timefreq/service/time-servers.html

更多的时间服务器列表请参考以下网站:

http://www.eecis.udel.edu/~mills/ntp/servers.html

二、Time Protocol (RFC-868)协议

  Time Protocol (RFC-868)协议是一种较简单的协议。此协议提供了一个独立于站点的,机器可读的日期和时间信息。时间服务返回的是以秒数,是从1900年1月1日午夜到现在的秒数。
  这个协议可以工作在TCP和UDP协议下。下面是通过TCP协议工作的时间协议的工作过程:这里S代表服务器,C代表客户。

S: 检测端口37

U: 连接到端口37

S: 以32位二进制数发送时间

U: 接收时间

U: 关闭连接

S: 关闭连接

如果服务器不能决定现在是什么时间,服务器会拒绝连接或不发送任何数据而直接关闭连接。

下面我们看看使用UDP协议的情况:这里S代表服务器,C代表客户。

S: 检测端口37

U: 发送一个空数据报到端口37

S: 接收这个空数据报

S: 发送包含32位二进制数(用于表示时间)的数据报

U: 接收时间数据报
如果服务器不能决定现在是什么时间,服务器会抛弃接收到的数据报而不作出任何应答。

三、网络对时的程序实现

  下面是使用TCP协议的实现网络对时的部分代码。GetRemoteTime 函数主要通过连接服务器szSever,并取得其回传的32位值:
BOOL GetRemoteTime(char* szSever, unsigned long& ulTime)

{

	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);	//使用UDP协议

	if(sock == INVALID_SOCKET)

	{

		return FALSE;

	}	

	sockaddr_in severAddr;

	severAddr.sin_family = AF_INET;

	severAddr.sin_port = htons(NET_TIME_PORT); 				

	severAddr.sin_addr.S_un.S_addr = inet_addr(szSever);



	if (sendto(sock, (char*)&ulTime, 4, 0, (sockaddr*)&severAddr, sizeof(severAddr)) == 4)

	{

		unsigned long flag = 1; 	

		if ((ioctlsocket(sock, FIONBIO, &flag) == 0))

		{	

			struct fd_set mask;			

			FD_ZERO(&mask);

			FD_SET(sock, &mask);

			

			struct timeval timeout;

			timeout.tv_sec = TIMEOUT_RECEIVE;

			timeout.tv_usec = 0;

			

			if (select(0, &mask, NULL, NULL, &timeout) == 1)

			{				

				if (recv(sock, (char*)&ulTime, 4, 0) == 4)

				{

					ulTime = ntohl(ulTime);

					closesocket(sock);

					return TRUE;

				}			

			}

		}

	}

	closesocket(sock);

	return FALSE;

}

      
MySetTime 函数的功能是将32位值转换为系统时间,并设置系统时间。
void MySetTime(unsigned long ulTime)

{

	FILETIME ft;

	SYSTEMTIME st;

	

	st.wYear = 1900;

	st.wMonth = 1;

	st.wDay = 1;

	st.wHour = 0;

	st.wMinute = 0;

	st.wSecond = 0;

	st.wMilliseconds = 0;

	

	SystemTimeToFileTime(&st, &ft);

	LARGE_INTEGER li = *(LARGE_INTEGER*)&ft;

	li.QuadPart  = (LONGLONG)10000000 * ulTime;

	ft = *(FILETIME*)&li;

	FileTimeToSystemTime(&ft, &st);	

	SetSystemTime(&st);

}



int APIENTRY WinMain(HINSTANCE hInstance,

		 HINSTANCE hPrevInstance,

		 LPSTR     lpCmdLine,

		 int       nCmdShow)

{

	//初始化TCP协议

	WSADATA wsaData;	

	if(WSAStartup(MAKEWORD(2,2), &wsaData)!= 0)

	{

		MessageBox(NULL, "初始化网络协议失败!", "错误报告", MB_OK|MB_ICONHAND);

		return -1;

	}

	

	int i = 0;

	unsigned long ulTime = 0;

	

	while (sever[i] != NULL)

	{

		if (GetRemoteTime(sever[i], ulTime))

		{

			MySetTime(ulTime);

			char buff[100];

			sprintf(buff, "已成功与时间服务器\r\n%s\r\n的时间同步", sever[i]);

			MessageBox(NULL, buff, "成功报告", MB_OK|MB_ICONINFORMATION);

			return 0;

		}

		i  ;

	}	

	MessageBox(NULL, "所有服务器均不能正常连接或超时!", "错误报告", MB_OK|MB_ICONHAND);

	WSACleanup();

	return 0;

}

       
 
本文章更多内容1 - 2 - 下一页>>
相关文章

Branch,docking和volatile objects
Ado 实现C 对象的存取
利用IEHelper实现IE弹出窗口过滤
彩电故障信息共享系统
模拟信息加密流程图简介
reference memory ,or when及其它
使用 ManWrap 库在本机 C 代码中调用.NET
浅析VC与matlab接口编程(一)
ADO开发中如何得到表格字段名
MSComm 控件的 Modem 通讯
托管应用中的意外错误
定制调试诊断工具和实用程序——摆脱DLL“地
杂谈:项目管理的是与非
教你如何作弊玩扫雷
使用
COM 组件设计与应用(十七)——持续性
基于DirectShow非线性编辑DES
阻止全局钩子的加载
类似 MSN 信息发送框的制作(上)
Python 的数据库操作

相关评论


本文章所属分类:首页 VC++

  热门关键字: