主頁 > 知識(shí)庫 > Lua獲取網(wǎng)絡(luò)時(shí)間(獲取時(shí)間同步服務(wù)器的時(shí)間)

Lua獲取網(wǎng)絡(luò)時(shí)間(獲取時(shí)間同步服務(wù)器的時(shí)間)

熱門標(biāo)簽:武漢外呼防封系統(tǒng)多少錢 清朝地圖標(biāo)注哈爾濱 冀州市地圖標(biāo)注 新岸線智能電銷機(jī)器人 漳州智云呼電話機(jī)器人 百度地圖標(biāo)注早餐區(qū)域 個(gè)人怎么在地圖標(biāo)注需要的店鋪 地圖標(biāo)注大廈 怎么去除地圖標(biāo)注

網(wǎng)絡(luò)授時(shí)服務(wù)是一些網(wǎng)絡(luò)上的時(shí)間服務(wù)器提供的時(shí)間,一般用于本地時(shí)鐘同步。 授時(shí)服務(wù)有很多種,一般我們選擇RFC-868。這個(gè)協(xié)議的工作流程是:(S代表Server,C代表Client)

S: 檢測端口37
U: 連接到端口37
S: 以32位二進(jìn)制數(shù)發(fā)送時(shí)間
U: 接收時(shí)間
U: 關(guān)閉連接
S: 關(guān)閉連接
協(xié)議非常簡單,用TCP連接上后,服務(wù)器直接把時(shí)間發(fā)送回來。發(fā)送的是從1900年1月1日午夜到現(xiàn)在的秒數(shù)。

使用luasocket
實(shí)現(xiàn)的方案有很多種,Lua不一定是最簡單的,選擇只是出于個(gè)人興趣。直接上代碼吧

-----------------------------------------------------------------------------
-- Network Time Protocal
-- Author: ani_di
-----------------------------------------------------------------------------
package.cpath = package.cpath .. ';D:\\tools\\Lua\\5.1\\clibs\\?.dll;?.dll'
local socket = 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"}

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 = socket.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


代碼原理不細(xì)說,非常簡單。唯一值得一提的是socket庫包含。最開始用的這句 require "socket"

在解釋器中表現(xiàn)很好,但在用C中調(diào)用會(huì)找不到相應(yīng)的module。錯(cuò)誤提示

  no field package.preload['socket']
  no file '.\socket.lua'
  no file 'F:\Projects\Lua\nettime\lua\socket.lua'
  no file 'F:\Projects\Lua\nettime\lua\socket\init.lua'
  no file 'F:\Projects\Lua\nettime\socket.lua'
  no file 'F:\Projects\Lua\nettime\socket\init.lua'
  no file 'D:\tools\Lua\5.1\lua\socket.luac'
  no file '.\socket.dll'
  no file '.\socket51.dll'
  no file 'F:\Projects\Lua\nettime\socket.dll'
  no file 'F:\Projects\Lua\nettime\socket51.dll'
  no file 'F:\Projects\Lua\nettime\clibs\socket.dll'
  no file 'F:\Projects\Lua\nettime\clibs\socket51.dll'
  no file 'F:\Projects\Lua\nettime\loadall.dll'
  no file 'F:\Projects\Lua\nettime\clibs\loadall.dll'.


網(wǎng)上也有好多類似的提問,大抵是沒仔細(xì)看作者的Guide。顯著的有這么一句

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

至于"socket.core",windows默認(rèn)安裝位于“\socket\core.dll”。

C宿主調(diào)用

#include stdio.h>
#include string.h>
#include lua.h>
#include lauxlib.h>
#include lualib.h>
#include time.h>
#include Windows.h>

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, "nettime.lua") || 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", st.wYear, st.wMonth, st.wDay);
      SetSystemTime(st);
    }
    break;
  } else {
    puts("No network!");
    Sleep(10000);
  }
  } while (1);
  lua_close(L);
  return 0;
}

標(biāo)簽:德宏 天門 濰坊 臺(tái)灣 宣城 天門 儋州 金昌

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Lua獲取網(wǎng)絡(luò)時(shí)間(獲取時(shí)間同步服務(wù)器的時(shí)間)》,本文關(guān)鍵詞  Lua,獲取,網(wǎng)絡(luò),時(shí)間,同步,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Lua獲取網(wǎng)絡(luò)時(shí)間(獲取時(shí)間同步服務(wù)器的時(shí)間)》相關(guān)的同類信息!
  • 本頁收集關(guān)于Lua獲取網(wǎng)絡(luò)時(shí)間(獲取時(shí)間同步服務(wù)器的時(shí)間)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章