Network timer service is the time provided by time servers on some networks, which are generally used for local clock synchronization. There are many types of timekeeping services, and we generally choose RFC-868. The workflow of this protocol is: (S stands for Server, C stands for Client)
S: Detection port 37
U: Connect to port 37
S: Send time with 32-bit binary number
U: Receive time
U: Close the connection
S: Close the connection
The protocol is very simple. After connecting to TCP, the server will send the time back directly. The number of seconds sent from midnight on January 1, 1900 to the present.
Using luasocket
There are many ways to implement it. Lua is not necessarily the simplest, and the choice is only out of personal interests. Just upload the code
----------------------------------------------------------------------------- -- Network Time Protocal -- Author: ani_di ----------------------------------------------------------------------------- = .. ';D:\\tools\\Lua\\5.1\\clibs\\?.dll;?.dll' local socket = require "" 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"} function nstol(str) assert(str and #str == 4) local t = {str:byte(1,-1)} local n = 0 for k = 1, #t do n= n*256 + t[k] end return n end -- get time from a ip address, use tcp protocl function gettime(ip) print('connect ', ip) local tcp = () tcp:settimeout(10) tcp:connect(ip, 37) success, time = pcall(nstol, tcp:receive(4)) tcp:close() return success and time or nil end function nettime() for _, ip in pairs(server_ip) do time = gettime(ip) if time then return time end end end
The code principle is not detailed, it is very simple. The only thing worth mentioning is the socket library contains. The first sentence required "socket"
It's good in the interpreter, but the corresponding module cannot be found when calling in C. Error message
no field ['socket'] no file '.\' no file 'F:\Projects\Lua\nettime\lua\' no file 'F:\Projects\Lua\nettime\lua\socket\' no file 'F:\Projects\Lua\nettime\' no file 'F:\Projects\Lua\nettime\socket\' no file 'D:\tools\Lua\5.1\lua\' no file '.\' no file '.\' no file 'F:\Projects\Lua\nettime\' no file 'F:\Projects\Lua\nettime\' no file 'F:\Projects\Lua\nettime\clibs\' no file 'F:\Projects\Lua\nettime\clibs\' no file 'F:\Projects\Lua\nettime\' no file 'F:\Projects\Lua\nettime\clibs\'.
There are many similar questions on the Internet, probably because I didn’t look at the author’s Guide carefully. There is a significant sentence
The other two environment variables instruct the compatibility module to look for dynamic libraries and extension modules in the appropriate directories and with the appropriate filename extensions.>
LUAPATH=/?.lua;?.lua LUACPATH=/?.dll;?.dll
As for "", the default installation of windows is located in "\socket\".
C Host Call
#include <> #include <> #include <> #include <> #include <> #include <> #include <> int load(lua_State* L, const char* func, unsigned int* utc) { lua_getglobal(L, func); if (lua_pcall(L, 0, 1, 0)) { printf("Error Msg pcall %s.\n", lua_tostring(L, -1)); return -1; } if (!lua_isnumber(L,-1)) { printf("time should be a number\n" ); return -2; } *utc = lua_tonumber(L,-1); lua_pop(L, -1); return 0; } void TimetToFileTime( time_t t, LPFILETIME pft ) { LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000; pft->dwLowDateTime = (DWORD) ll; pft->dwHighDateTime = ll >>32; } int main() { lua_State* L = luaL_newstate(); unsigned int utc = 0; luaL_openlibs(L); if (luaL_loadfile(L, "") || lua_pcall(L, 0, 0, 0)) { printf("Error Msg load %s.\n", lua_tostring(L, -1)); return -1; } do { if(load(L,"nettime", &utc) == 0) { time_t tt = utc - 2208988800L; SYSTEMTIME st; FILETIME ft; TimetToFileTime(tt, &ft); if (FileTimeToSystemTime(&ft, &st)) { printf("Today is: %d-%d-%d\n", , , ); SetSystemTime(&st); } break; } else { puts("No network!"); Sleep(10000); } } while (1); lua_close(L); return 0; }