歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Python中使用socket如何實(shí)現(xiàn)時(shí)間同步?

發(fā)布時(shí)間:2017-09-05 20:56  回復(fù):0  查看:2385   最后回復(fù):2017-09-05 20:56  
本文和大家分享的主要是python 中使用socket 實(shí)現(xiàn)時(shí)間同步相關(guān)內(nèi)容,一起來看看吧,希望對大家 學(xué)習(xí)python有所幫助。
  在這里通過一個(gè)最簡單的時(shí)間協(xié)議來學(xué)習(xí)socket 的使用,最古老的時(shí)間協(xié)議是 RFC868 ,它的定義如下:
  RFC868  時(shí)間協(xié)議
 ?。?/span>RFC868 Time Protocol
  本RFC 規(guī)范了一個(gè) ARPA Internet community 上的標(biāo)準(zhǔn)。在 ARPA Internet 上的所有主機(jī)應(yīng)當(dāng)采用和實(shí)現(xiàn)這個(gè)標(biāo)準(zhǔn)。
  此協(xié)議提供了一個(gè)獨(dú)立于站點(diǎn)的,機(jī)器可讀的日期和時(shí)間信息。時(shí)間服務(wù)返回的是以秒數(shù),是從1900 1 1 日午夜到現(xiàn)在的秒數(shù),天哪,也不小呢。
  設(shè)計(jì)這個(gè)協(xié)議的一個(gè)重要目的在于,網(wǎng)絡(luò)上的許多主機(jī)并沒有時(shí)間的觀念,在分布式的系統(tǒng)上,我們可以想一想,北京的時(shí)間和東京的時(shí)間如何分呢?主機(jī)的時(shí)間往往可以人為改變,而且因?yàn)闄C(jī)器時(shí)鐘內(nèi)的誤差而變得不一致,因此需要使用時(shí)間服務(wù)器通過選舉方式得到網(wǎng)絡(luò)時(shí)間,讓服務(wù)器有一個(gè)準(zhǔn)確的時(shí)間觀念。不要小看時(shí)間,這對于一些以時(shí)間為標(biāo)準(zhǔn)的分布運(yùn)行的程序簡單是太重要了。
  這個(gè)協(xié)議可以工作在TCP UDP 協(xié)議下。下面是通過 TCP 協(xié)議工作的時(shí)間協(xié)議的工作過程:這里 S 代表服務(wù)器, C 代表客戶。
  S:  檢測端口 37
  U:  連接到端口 37
  S:  32 位二進(jìn)制數(shù)發(fā)送時(shí)間
  U:  接收時(shí)間
  U:  關(guān)閉連接
  S:  關(guān)閉連接
  服務(wù)器在端口37 上監(jiān)聽連接。當(dāng)連接建立后,服務(wù)器返回一個(gè) 32 位的時(shí)間值,然后關(guān)閉連接。這個(gè)過程也不難,如果服務(wù)器不能決定現(xiàn)在是什么時(shí)間,服務(wù)器會拒絕連接或不發(fā)送任何數(shù)據(jù)而直接關(guān)閉連接。
  下面我們看看使用UDP 協(xié)議的情況:這里 S 代表服務(wù)器, C 代表客戶。
  S:  檢測端口 37
  U:  發(fā)送一個(gè)空數(shù)據(jù)報(bào)到端口 37
  S:  接收這個(gè)空數(shù)據(jù)報(bào)
  S:  發(fā)送包含 32 位二進(jìn)制數(shù)(用于表示時(shí)間)的數(shù)據(jù)報(bào)
  U:  接收時(shí)間數(shù)據(jù)報(bào)
  服務(wù)器在端口37 上監(jiān)聽數(shù)據(jù)包。當(dāng)一個(gè)數(shù)據(jù)包來后,服務(wù)器返回一個(gè)包含 32 位的時(shí)間的數(shù)據(jù)包。這個(gè)過程也不難,如果服務(wù)器不能決定現(xiàn)在是什么時(shí)間,服務(wù)器會拋棄接收到的數(shù)據(jù)報(bào)而不作出任何應(yīng)答。
  時(shí)間
  時(shí)間是由32 位表示的,是自 1900 1 1 0 時(shí)到當(dāng)前的秒數(shù),我們可以計(jì)算一下,這個(gè)協(xié)議只能表示到 2036 年就不能用了。(但是我們也知道計(jì)算機(jī)發(fā)展速度這么快,可能到時(shí)候就會有更好的協(xié)議代替這個(gè)協(xié)議,或者有已經(jīng)想出有效的解決辦法了。)
  下面是
  些例子:
  the time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT,
  2,398,291,200 corresponds to 00:00 1 Jan 1976 GMT,
  2,524,521,600 corresponds to 00:00 1 Jan 1980 GMT,
  2,629,584,000 corresponds to 00:00 1 May 1983 GMT,
  以及 -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.
  RFC868-Time Protocol RFC868  時(shí)間協(xié)議
  1
  1
  中文文檔翻譯計(jì)劃
  下面的客戶端實(shí)現(xiàn)時(shí)間協(xié)議,從時(shí)間服務(wù)器獲取當(dāng)前時(shí)間返回,并解釋打印出來,其實(shí)就可以利用這么簡單的協(xié)議來同步你的樹莓派電腦的時(shí)間。協(xié)議比較簡單主要接收4 個(gè)字節(jié)即可。
  # File: socket-example-1.py
  import  socket
  import struct,  time
  # server
  HOST = "time.nist.gov"
  PORT = 37
  # reference time (in seconds since 1900-01-01 00:00:00)
  TIME1970 = 2208988800 # 1970-01-01 00:00:00
  # connect to server
  s =  socket. socket( socket.AF_INET,  socket.SOCK_STREAM)
  s.connect((HOST, PORT))
  # read 4 bytes, and convert to time value
  t = s.recv(4)
  t = struct.unpack("!I", t)[0]
  t = int(t - TIME1970)
  s. close()
  # print results
  print("server time is",  time.ctime(t))
  print("local clock is", int( time. time()) - t, "seconds off")
  輸出結(jié)果如下:
  ======= RESTART: D:/work/csdn/python_Game1/example/socket-example-1.py =======
  server time is Fri Sep  1 18:31:50 2017
  local clock is -269 seconds off
  >>>
來源: 大坡3D 軟件開發(fā)
您還未登錄,請先登錄

熱門帖子

最新帖子

?