SoFunction
Updated on 2025-04-11

Lua gets network time (gets the time of the time synchronization server)

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;
}