本文和大家分享的主要是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ā)