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

📄 net_time.cpp

📁 RFC686时间同步的服务器段和客户端代码 包括TCP和UDP
💻 CPP
字号:
#pragma warning(disable: 4530)
#pragma warning(disable: 4786)

#include <iostream>
#include <ctime>
#include <cassert>
using namespace std;
#include <winsock2.h>
#include <windows.h>

static char * get_error_msg()
{
	static char msg_buf[1024];
	FormatMessage( 
		FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		msg_buf,
		1023,
		NULL
		);
	return msg_buf;
}

void time_internet_to_local(void *recv_buf) //接到的数据转换为本地时间
{
	assert(recv_buf);
	char p[4], *precv = ((char *)recv_buf) + 3;
	for(int i=0; i<4; i++)
		p[i] = *precv--;
	*(long *)p -= 2208988800;

	SYSTEMTIME st;
	tm * ptm = gmtime((time_t *)p);
	st.wYear = 	ptm->tm_year + 1900;
	st.wMonth = ptm->tm_mon + 1;
	st.wDay = ptm->tm_mday;
	st.wHour = ptm->tm_hour;
	st.wMinute = ptm->tm_min;
	st.wSecond = ptm->tm_sec;
	st.wMilliseconds = 0;
	SetSystemTime(&st);
}

void print_time(void *recv_buf)//打印接到的数据
{
	assert(recv_buf);
	char p[4], *precv = ((char *)recv_buf) + 3;
	for(int i=0; i<4; i++)
		p[i] = *precv--;
	*(long *)p -= 2208988800; 
	char buf[15];
	strftime(buf, 80, "%Y-%m-%d %H:%M:%S", localtime((time_t *)p));
	cout << buf << endl;
}

void tcp(void *ip)//RFC868 PORT 37 TCP协议
{
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(37);
	server.sin_addr.s_addr = inet_addr((char *)ip) ; 

	SOCKET s = socket(AF_INET, SOCK_STREAM, 0); 
	if(s == INVALID_SOCKET)
		cout << __LINE__<<"  socket error  : " << WSAGetLastError() << endl; 

	int ret = connect(s, (struct sockaddr*)&server, sizeof(server));
	if(ret == SOCKET_ERROR)
		cout << __LINE__ << get_error_msg() << endl;
	else
	{
		char xx[4];
		ret = recv(s, xx, 4, 0);
		if(ret == SOCKET_ERROR)	
			cout << __LINE__ << get_error_msg() << endl;
		else
		{
			print_time(xx);
			//time_internet_to_local(xx);设定本地时间 最好加一个判断网络延时
		}

		if(shutdown(s, SD_RECEIVE) == SOCKET_ERROR)
			cout << __LINE__ << get_error_msg() << endl;
	}
	closesocket(s);
}

void udp(void *ip) //RFC868 PORT 37 UDP
{
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(37);
	server.sin_addr.s_addr = inet_addr((char *)ip) ; 
	
	SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
	if(s == INVALID_SOCKET)
	{
		cout << __LINE__ << get_error_msg() << endl;
	}

	int ret, c_len = sizeof(server);
	char r_buf[4];
	ret = sendto(s, r_buf, 0, 0, (struct sockaddr *)&server, sizeof(server));
	if(ret == SOCKET_ERROR)
		cout << __LINE__ << get_error_msg() << endl;

	FD_SET read_set;
	timeval tv = {3, 0}; //tv.tv_sec = 0, tv.tv_usec = 100000;	0.1s
	FD_ZERO(&read_set);
	FD_SET(s, &read_set);
	ret = select(0, &read_set, NULL, NULL, &tv);
	if(ret == SOCKET_ERROR)
	{
		cout << __LINE__ << get_error_msg() << endl;
	}
	else
		if(FD_ISSET(s, &read_set))
		{
			ret = recvfrom(s, r_buf, 4, 0, (struct sockaddr *)&server, &c_len);
			
			if(ret == SOCKET_ERROR)
				cout << __LINE__ << get_error_msg() << endl;
			else
			{
				print_time(r_buf);
			}
		}
	closesocket(s);
}

int main(int argc, char *argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(2, 2);
	WSAStartup(wVersionRequested, &wsaData);

	char *ipcn = "159.226.154.16";//国家授时中心
	char *iphk = "210.0.235.14";//香港天文台授时中心
	char *iplocal = "192.18.17.3";

	time_t now;
	char buf[15] = {0};

	now = time(NULL);
	strftime(buf, 80, "%Y-%m-%d %H:%M:%S", localtime(&now));
	cout << "TCP 连接国家授时中心 " << endl << "本地时间 " << buf << endl << "远程时间 ";
	tcp(ipcn);

	now = time(NULL);
	strftime(buf, 80, "%Y-%m-%d %H:%M:%S", localtime(&now));
	cout << "UDP 连接香港天文台授时中心 " << endl << "本地时间 " << buf << endl << "远程时间 ";
	udp(iphk);	  

	now = time(NULL);
	strftime(buf, 80, "%Y-%m-%d %H:%M:%S", localtime(&now));
	cout << "TCP 连接 " << iplocal << endl << "本地时间 " << buf << endl << "远程时间 ";
	tcp(iplocal); 

	WSACleanup(); 
	return 0;
}

⌨️ 快捷键说明

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