Lua获取网络时间(获取时间同步服务器的时间)
网络授时服务是一些网络上的时间服务器提供的时间,一般用于本地时钟同步。授时服务有很多种,一般我们选择RFC-868。这个协议的工作流程是:(S代表Server,C代表Client)
S:检测端口37
U:连接到端口37
S:以32位二进制数发送时间
U:接收时间
U:关闭连接
S:关闭连接
协议非常简单,用TCP连接上后,服务器直接把时间发送回来。发送的是从1900年1月1日午夜到现在的秒数。
使用luasocket
实现的方案有很多种,Lua不一定是最简单的,选择只是出于个人兴趣。直接上代码吧
-----------------------------------------------------------------------------
--NetworkTimeProtocal
--Author:ani_di
-----------------------------------------------------------------------------
package.cpath=package.cpath..';D:\\tools\\Lua\\5.1\\clibs\\?.dll;?.dll'
localsocket=require"socket.core"
server_ip={
--"129.6.15.29",
"132.163.4.101",
"132.163.4.102",
"132.163.4.103",
"128.138.140.44",
"192.43.244.18",
"131.107.1.10",
"66.243.43.21",
"216.200.93.8",
"208.184.49.9",
"207.126.98.204",
"207.200.81.113",
"205.188.185.33"}
functionnstol(str)
assert(strand#str==4)
localt={str:byte(1,-1)}
localn=0
fork=1,#tdo
n=n*256+t[k]
end
returnn
end
--gettimefromaipaddress,usetcpprotocl
functiongettime(ip)
print('connect',ip)
localtcp=socket.tcp()
tcp:settimeout(10)
tcp:connect(ip,37)
success,time=pcall(nstol,tcp:receive(4))
tcp:close()
returnsuccessandtimeornil
end
functionnettime()
for_,ipinpairs(server_ip)do
time=gettime(ip)
iftimethen
returntime
end
end
end
代码原理不细说,非常简单。唯一值得一提的是socket库包含。最开始用的这句require"socket"
在解释器中表现很好,但在用C中调用会找不到相应的module。错误提示
nofieldpackage.preload['socket'] nofile'.\socket.lua' nofile'F:\Projects\Lua\nettime\lua\socket.lua' nofile'F:\Projects\Lua\nettime\lua\socket\init.lua' nofile'F:\Projects\Lua\nettime\socket.lua' nofile'F:\Projects\Lua\nettime\socket\init.lua' nofile'D:\tools\Lua\5.1\lua\socket.luac' nofile'.\socket.dll' nofile'.\socket51.dll' nofile'F:\Projects\Lua\nettime\socket.dll' nofile'F:\Projects\Lua\nettime\socket51.dll' nofile'F:\Projects\Lua\nettime\clibs\socket.dll' nofile'F:\Projects\Lua\nettime\clibs\socket51.dll' nofile'F:\Projects\Lua\nettime\loadall.dll' nofile'F:\Projects\Lua\nettime\clibs\loadall.dll'.
网上也有好多类似的提问,大抵是没仔细看作者的Guide。显著的有这么一句
Theothertwoenvironmentvariablesinstructthecompatibilitymoduletolookfordynamiclibrariesandextensionmodulesintheappropriatedirectoriesandwiththeappropriatefilenameextensions.>
LUAPATH=/?.lua;?.luaLUACPATH=/?.dll;?.dll
至于"socket.core",windows默认安装位于“\socket\core.dll”。
C宿主调用
#include<stdio.h>
#include<string.h>
#include<lua.h>
#include<lauxlib.h>
#include<lualib.h>
#include<time.h>
#include<Windows.h>
intload(lua_State*L,constchar*func,unsignedint*utc){
lua_getglobal(L,func);
if(lua_pcall(L,0,1,0)){
printf("ErrorMsgpcall%s.\n",lua_tostring(L,-1));
return-1;
}
if(!lua_isnumber(L,-1)){
printf("timeshouldbeanumber\n");
return-2;
}
*utc=lua_tonumber(L,-1);
lua_pop(L,-1);
return0;
}
voidTimetToFileTime(time_tt,LPFILETIMEpft)
{
LONGLONGll=Int32x32To64(t,10000000)+116444736000000000;
pft->dwLowDateTime=(DWORD)ll;
pft->dwHighDateTime=ll>>32;
}
intmain()
{
lua_State*L=luaL_newstate();
unsignedintutc=0;
luaL_openlibs(L);
if(luaL_loadfile(L,"nettime.lua")||lua_pcall(L,0,0,0)){
printf("ErrorMsgload%s.\n",lua_tostring(L,-1));
return-1;
}
do{
if(load(L,"nettime",&utc)==0){
time_ttt=utc-2208988800L;
SYSTEMTIMEst;
FILETIMEft;
TimetToFileTime(tt,&ft);
if(FileTimeToSystemTime(&ft,&st))
{
printf("Todayis:%d-%d-%d\n",st.wYear,st.wMonth,st.wDay);
SetSystemTime(&st);
}
break;
}else{
puts("Nonetwork!");
Sleep(10000);
}
}while(1);
lua_close(L);
return0;
}
热门推荐
10 五一公司放假祝福语简短
11 追星女孩的祝福语简短
12 给长辈端午祝福语 简短
13 生日祝福语有诗意简短
14 团圆日祝福语简短
15 中秋商务祝福语简短最新
16 温暖文艺简短祝福语短句
17 男孩上学祝福语简短的
18 入住酒店文案祝福语简短