mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #
 | |
| # Module vtime - Keep virtual time between two nodes.
 | |
| #
 | |
| # We try for synchronised clocks by sending a packet of the for
 | |
| # (1,mytime,0) to the other side, and waiting (at most) a second for
 | |
| # a reply. This reply has the form (2,mytime,histime), and we can
 | |
| # estimate the time difference by defining histime to be exactly half-way
 | |
| # between the time we sent our message and got our reply. We send a
 | |
| # final (3,mynewtime,histime) message to allow the other side to do the
 | |
| # same computations.
 | |
| #
 | |
| # Note that the protocol suffers heavily from the 2-army problem.
 | |
| # It'll have to do until I can read up on time-sync protocols, though.
 | |
| #
 | |
| from socket import *
 | |
| import time
 | |
| 
 | |
| MSGSIZE = 100
 | |
| MSGTIMEOUT = 1000
 | |
| 
 | |
| recv_timeout = 'receive timeout'
 | |
| bad_connect = 'Bad connection'
 | |
| 
 | |
| def timeavg(a,b):
 | |
|     return int((long(a)+b)/2L)
 | |
| def tryrecv(s):
 | |
|     cnt = 0
 | |
|     while 1:
 | |
| 	if s.avail():
 | |
| 	    return s.recvfrom(MSGSIZE)
 | |
| 	time.millisleep(100)
 | |
| 	cnt = cnt + 100
 | |
| 	if cnt > MSGTIMEOUT:
 | |
| 	    raise recv_timeout
 | |
| 
 | |
| class VTime():
 | |
|     def init(self,(client,host,port)):
 | |
| 	s = socket(AF_INET, SOCK_DGRAM)
 | |
| 	host = gethostbyname(host)
 | |
| 	localhost = gethostbyname(gethostname())
 | |
| 	raddr = (host,port)
 | |
| 	s.bind((localhost,port))
 | |
| 	if client:
 | |
| 	    #
 | |
| 	    # We loop here because we want the *second* measurement
 | |
| 	    # for accuracy
 | |
| 	    for loopct in (0,2):
 | |
| 		curtijd = time.millitimer()
 | |
| 		check = `(loopct,curtijd,0)`
 | |
| 		s.sendto(check,raddr)
 | |
| 		while 1:
 | |
| 		    try:
 | |
| 			if loopct:
 | |
| 			    data, other = s.recvfrom(MSGSIZE)
 | |
| 			else:
 | |
| 			    data, other = tryrecv(s)
 | |
| 			newtijd = time.millitimer()
 | |
| 			if other <> raddr:
 | |
| 			    print 'Someone else syncing to us: ', other
 | |
| 			    raise bad_connect
 | |
| 			data = eval(data)
 | |
| 			if data[:2] == (loopct+1,curtijd):
 | |
| 			    break
 | |
| 			if data[0] <> 2:
 | |
| 			    print 'Illegal sync reply: ', data
 | |
| 			    raise bad_connect
 | |
| 		    except recv_timeout:
 | |
| 			curtijd = time.millitimer()
 | |
| 			check = `(loopct,curtijd,0)`
 | |
| 			s.sendto(check,raddr)
 | |
| 	    histime = data[2]
 | |
| 	    s.sendto(`(4,newtijd,histime)`,raddr)
 | |
| 	    mytime = timeavg(curtijd,newtijd)
 | |
| 	    #mytime = curtijd
 | |
| 	    self.timediff = histime - mytime
 | |
| 	else:
 | |
| 	    while 1:
 | |
| 		data,other = s.recvfrom(MSGSIZE)
 | |
| 		if other <> raddr:
 | |
| 		    print 'Someone else syncing to us: ', other, ' Wanted ', raddr
 | |
| 		    raise bad_connect
 | |
| 		data = eval(data)
 | |
| 		if data[0] in (0,2):
 | |
| 		    curtijd = time.millitimer()
 | |
| 		    s.sendto(`(data[0]+1,data[1],curtijd)`,raddr)
 | |
| 		elif data[0] == 4:
 | |
| 		    newtijd = time.millitimer()
 | |
| 		    histime = data[1]
 | |
| 		    mytime = timeavg(curtijd,newtijd)
 | |
| 		    #mytime = curtijd
 | |
| 		    self.timediff = histime-mytime
 | |
| 		    break
 | |
| 		else:
 | |
| 		    print 'Funny data: ', data
 | |
| 		    raise bad_connect
 | |
| 	return self
 | |
| 	#
 | |
|     def his2mine(self,tijd):
 | |
| 	return tijd - self.timediff
 | |
|     #
 | |
|     def mine2his(self, tijd):
 | |
| 	return tijd + self.timediff
 | |
| 
 | |
| def test(clt, host, port):
 | |
|     xx = VTime().init(clt,host,port)
 | |
|     print 'Time diff: ', xx.his2mine(0)
 | 
