Created
September 3, 2018 09:06
-
-
Save dendentang/03e905343055ef099c88c75926c07f8d to your computer and use it in GitHub Desktop.
simple python3 ntp server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import socket | |
| import time | |
| import threading | |
| import select | |
| import sys | |
| import ntplib | |
| if sys.version_info[0] == 2: | |
| import Queue as queue | |
| else: | |
| import queue | |
| class RecvThread(threading.Thread): | |
| def __init__(self, sock, taskQueue): | |
| threading.Thread.__init__(self) | |
| self.sock = sock | |
| self.taskQueue = taskQueue | |
| def run(self): | |
| while True: | |
| rlist, wlist, elist = select.select([self.sock], [], [], 1) | |
| if len(rlist) != 0: | |
| for tempSocket in rlist: | |
| try: | |
| data, addr = tempSocket.recvfrom(1024) | |
| recvTimestamp = ntplib.system_to_ntp_time(time.time()) | |
| self.taskQueue.put((data, addr, recvTimestamp)) | |
| except socket.error as msg: | |
| pass | |
| class WorkThread(threading.Thread): | |
| def __init__(self, sock, taskQueue): | |
| threading.Thread.__init__(self) | |
| self.sock = sock | |
| self.taskQueue = taskQueue | |
| def run(self): | |
| while True: | |
| try: | |
| data, addr, recvTimestamp = self.taskQueue.get(timeout=1) | |
| recvPacket = ntplib.NTPPacket() | |
| recvPacket.from_data(data) | |
| timeStamp_high = ntplib._to_int(recvPacket.tx_timestamp) | |
| timeStamp_low = ntplib._to_frac(recvPacket.tx_timestamp) | |
| sendPacket = ntplib.NTPPacket(version=3, mode=4) | |
| sendPacket.stratum = 2 | |
| sendPacket.poll = 10 | |
| sendPacket.ref_timestamp = recvTimestamp-5 | |
| sendPacket.orig_timestamp = ntplib._to_time(timeStamp_high, | |
| timeStamp_low) | |
| sendPacket.recv_timestamp = recvTimestamp | |
| sendPacket.tx_timestamp = ntplib.system_to_ntp_time( | |
| time.time()) | |
| self.sock.sendto(sendPacket.to_data(), addr) | |
| except queue.Empty: | |
| continue | |
| except ntplib.NTPException: | |
| continue | |
| def startServer(listenIp="0.0.0.0", listenPort=123): | |
| taskQueue = queue.Queue() | |
| sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
| sock.bind((listenIp, listenPort)) | |
| recvThread = RecvThread(sock, taskQueue) | |
| recvThread.daemon = True | |
| recvThread.start() | |
| workThread = WorkThread(sock, taskQueue) | |
| workThread.daemon = True | |
| workThread.start() | |
| while True: | |
| try: | |
| time.sleep(0.5) | |
| except KeyboardInterrupt: | |
| sys.exit(0) | |
| if __name__ == "__main__": | |
| startServer() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment