https://github.com/yubars/mbb
Tip revision: cd5de904332d33adabbc4793a87af7406ff26250 authored by yubars on 27 May 2014, 20:18:40 UTC
Create speed.py
Create speed.py
Tip revision: cd5de90
server.py
#!/usr/bin/python
import socket
import signal
import sys
import os
import inspect
from threading import Thread
import time
from time import strftime
import traceback
import string
import subprocess
import csv
import netifaces
import struct
import select
#global
BUFSIZE = 1024*8
THISFILENAME = inspect.getfile(inspect.currentframe())
#packet-related
PACKET_SIZE = 1460
HEADER_FORMAT = struct.Struct('dii')
PADDING_SIZE = PACKET_SIZE - HEADER_FORMAT.size
PADDING = os.urandom(PADDING_SIZE)
#SIGINT
def signal_handler( *args ):
print >> sys.stderr, 'SIGINT: Quit gracefully'
sys.exit(0)
#wait, clock syn, minutes
def wait_for_min( mins ):
print >> sys.stderr, '%s %s' % ( 'now:', time.strftime("%H:%M:%S", time.localtime(time.time())) )
future_time = time.time() + ( mins * 60 )
while True:
cur_time = time.time()
if( cur_time == future_time ):
break
delta = future_time - cur_time
if( delta > 1 ):
time.sleep(15)
#print something to wait until...
print >> sys.stderr, '%s %s , %s %s' % ( 'wait to sync at:', time.strftime("%H:%M:%S", time.localtime(future_time)), 'now:', time.strftime("%H:%M:%S", time.localtime(time.time())) )
else:
break
#UDP socket open
def set_udp_socket( iface, port ):
try:
#UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#s.setblocking(0) ???
server_addr = netifaces.ifaddresses(iface)[2][0]['addr']
s.bind( ( server_addr, port ) )
return s, server_addr
except socket.error as e:
print >> sys.stderr, "could not open socket: ", iface, e
if s:
s.close()
raise
#UDP socket close
def unset_socket( socket ):
try:
socket.close()
except socket.error as e:
print >> sys.stderr, "could not close socket: ", socket, e
raise
#receive
def recv_socket( s, epoch ):
rcv_packets = []
timeout = 300
client_addr = None
while True:
if client_addr == None:
recvready = select.select([s], [], [])
else:
recvready = select.select([s], [], [], timeout)
if not recvready[0]:
break
# receive
payload, client_addr = s.recvfrom(BUFSIZE)
recv_timestamp = time.time()
# reply
try:
s.sendto(payload, client_addr)
except Exception as e:
print >> sys.stderr, 'sendto error:', e
break
(send_timestamp, epoch, packet_nr) = HEADER_FORMAT.unpack(payload[:HEADER_FORMAT.size])
rcv_packets.append([recv_timestamp, epoch, packet_nr, recv_timestamp-send_timestamp])
return rcv_packets, client_addr
def evaluate_packet_delay( packets, epoch, nr_packets, filename ):
with open(filename + ".csv", "a") as csvfile:
w = csv.writer(csvfile, delimiter=',')
packet_dict={}
for packet in packets:
packet_dict[packet[2]] = packet
w.writerow(['timestamp', 'epoch', 'nr_packet', 'delta', 'jitter', 'owd'])
for curr in range(nr_packets):
try:
prev = curr - 1
curr_packet = packet_dict[curr]
prev_packet = packet_dict[prev]
except:
# there is no pair of packets
continue
delta = curr_packet[0] - prev_packet[0]
jitter = delta - 1.0
timestamp = int(round(curr_packet[0]))
owd = curr_packet[3]
w.writerow([timestamp, epoch, curr, delta, jitter, owd])
#client
def server( *args ):
finish = 0
server_addr = args[0]
server_port = args[1]
iface = args[2]
nr_packets = args[3]
nr_probe = args[4]
filename = args[5]
try:
epoch = 1
while( epoch <= nr_probe ):
try:
while True:
try:
socket, addr = set_udp_socket( iface, server_port )
print 'UDP: %s:%d' % (addr, server_port) + '\n'
break
except:
time.sleep(0.1)
print >> sys.stderr, '\n', 'wait for socket'
#recv: ON
print >> sys.stderr, '\n', 'SERVER - RECV'
rcv_packets, client_addr = recv_socket( socket, epoch )
evaluate_packet_delay( rcv_packets, epoch, nr_packets, ('SERVER-DELAY-'+iface+'-'+filename+time.strftime("%m%d%H:%M")) )
unset_socket( socket )
print >> sys.stderr, '\n', 'SERVER - DONE'
except:
e = sys.exc_info()
for file, linenr, function, text in traceback.extract_tb(e[2]):
error = '%s %s %s %s %s %s %s' % (file, 'line', linenr, 'in', function, '->', e[:2])
print >> sys.stderr, error;
wait_for_min( 0.1 )
epoch+=1
except( KeyboardInterrupt, SystemExit ):
print >> sys.stderr, 'close tcp socket: Exit! -> ',str(THISFILENAME);
finally:
error = '%s %s' % ('close tcp socket -> ',str(THISFILENAME))
print >> sys.stderr, error
try:
interfaceinfo.stop()
socket.close()
except:
pass
#usage:
def usage():
print >> sys.stderr, '\n' + str(THISFILENAME)+" [server IP] [server port] [interface] [nr. of packets (int)] [number of epoches (int)] [filename]" + '\n'
sys.exit(0)
#SERVER:
if __name__ == '__main__':
#SIGINT
signal.signal(signal.SIGINT, signal_handler)
if( len(sys.argv) < 7 ):
usage()
elif( len(sys.argv) == 7 ):
server_addr = sys.argv[1]
server_port = int(sys.argv[2])
iface = sys.argv[3]
nr_packets = int(sys.argv[4])
nr_probe = int(sys.argv[5])
filename = sys.argv[6]
#server
server(server_addr, server_port, iface, nr_packets, nr_probe, filename)
else:
usage()