Skip to content
Snippets Groups Projects
Select Git revision
  • abedf7600169b0d0b9ed016b09a162d9613bb2e6
  • master default protected
  • trustit
  • devel
4 results

register_test.rs

Blame
  • UDP-client-server.py 8.38 KiB
    import socket
    import time
    import sys
    import threading
    from threading import Thread
    import numpy as np
    from array import *
    
    # pymongo for MongoDB support
    import pymongo
    # For timestamping in MongoDB
    import datetime
    
    #pymongo connect
    DBConHost = 'localhost'
    DBConPort = 27017
    DBName = 'matningar'
    DBTableName = 'stability'
    
    DBCon = pymongo.MongoClient(DBConHost, DBConPort)
    DB = DBCon[DBName]
    DBTableStability = DB[DBTableName]
    
    
    #DEFINE INPUTS HERE
    #CLIENT - SENDER
    #UDP_DEST_IP = '::1'             # IP ADDRESS TO SEND DATAGRAMS TO  (v4 or v6)
    UDP_DEST_IP = '0.0.0.0'             # IP ADDRESS TO SEND DATAGRAMS TO  (v4 or v6)
    UDP_DEST_PORT = 15005           # IP PORT TO SEND DATAGRAMS TO
    PACKET_SIZE = 200               # DATAGRAM SIZE IN BYTES
    NR_OF_PACKETS = 100              # TOTAL NR. OF PACKETS TO SEND
    PACKETS_PER_SEC = 100           # PACKETS PER SECOND
    
    # CLIENT - RECEIVER
    #UDP_RECEIVE_IP = '::1'          # LISTENING IP ADDRESS (v6)
    UDP_RECEIVE_IP = '0.0.0.0'   # LISTENING IP ADDRESS (v4)
    UDP_RECEIVE_PORT = 55555        # IP PORT TO LISTEN FOR INCOMING PACKETS
    BUFFER = 4096
    
    
    #CLIENT-RECEIVER PART
    def udp_client_receive(UDP_RECEIVE_IP, UDP_RECEIVE_PORT):
        ADDR = (UDP_RECEIVE_IP, UDP_RECEIVE_PORT)
    
    #MAKE A DUMB IP VERSION CHECK
        if ':' in UDP_RECEIVE_IP:
            rcv_sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
        else:
            rcv_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
        global packet_count_rcvd
        global cumulative_delay
        global min_delay
        global max_delay
        global rt_delay_array
        global jitter
        min_delay = 100.
        max_delay = 0.
        rt_delay_array = array('f')
        packet_count_rcvd = 0
        cumulative_delay = 0.
        jitter = 0.
    
        try:
            rcv_sock.bind(ADDR)
            print('Server Listening on',  ADDR)
        except Exception:
            print('***ERROR: Server Port Binding Failed')
    
    #FIRE UP THE LISTENER ENGINES
        while True:
            data, addr = rcv_sock.recvfrom(BUFFER)
            data = data.decode("utf-8")
            splitdata = data.split(',')
            timecount = splitdata[0].strip("('")
            rt_delay = (time.time() - float(timecount))
            packet_number = str(splitdata[1].strip("' '"))
            packet_number = packet_number.lstrip('0')
    #WRITE TO FILE AND DO PACKET COUNT
    # Useful for debugging and verification purposes
    #        outfile = open("udp_twoway_results.csv", "a").\
    #            write(str(time.ctime() + ',' + 'received , ' +
    #                      packet_number + ' , ' + str(rt_delay) + '\n'))
    
    # Store all rt_delay for std.dev. calculation
    
            rt_delay_array.append(rt_delay)
    
    # Comment this line to disable per packet print
    
            #print((time.ctime() + ',' + 'received , ' +
                   #packet_number + ' , ' + str(rt_delay)))
    
    # Store minimum and maximum delay
            if rt_delay > max_delay:
                max_delay = rt_delay
            if rt_delay < min_delay:
                    min_delay = rt_delay
    
            packet_count_rcvd = packet_count_rcvd + 1
            cumulative_delay = cumulative_delay + rt_delay
    
        outfile.close()
    
    #DATA SUBSCRIPTION (callback)
    def cb_event(recipient, threshold):
        # TODO
    
        # Somebody call cb_event, identifying themselves with recipient
        # defining their threshold value when they want to be notified
    
        # Create list with recipient, threshold
        # Run as a separate thread and for example each 5 seconds check if
        # any of the thresholds are exceeded. Notify recpient as needed.
        print("TODO")
    
    
    #GET LOCALITY
    def get_loc():
        # Query locality group, return the bounding box for current loc
        #TODO
        loc = 0
    
        return loc
    
    #CLIENT SERVER SIDE
    def udp_client_send(UDP_DEST_IP,  UDP_DEST_PORT,
                        PACKET_SIZE,  NR_OF_PACKETS, PACKETS_PER_SEC):
    
        inter_departure_time = 1. / PACKETS_PER_SEC
        packet_count_snd = 0
    
        print("UDP Client Started")
        print("UDP target IP:", UDP_DEST_IP)
        print("UDP target port:", UDP_DEST_PORT)
        print("UDP Packets to Send:",  NR_OF_PACKETS)
    
    #IF IPv6
        if ':' in UDP_DEST_IP:
            if PACKET_SIZE > 97:  # BUILD DATAGRAM OF DESIRED SIZE
                padding = ''
                for j in range(98, PACKET_SIZE):
                    padding = padding + str(1)
            for i in range(1, NR_OF_PACKETS + 1):  # SEND SPECIFIED NR OF PKTS
                time.sleep(inter_departure_time)
                snd_sock6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
                snd_sock6.sendto(str(("%.5f" % time.time(), str('%08d' % i),
                                      padding)), (UDP_DEST_IP, UDP_DEST_PORT))
                packet_count_snd = packet_count_snd + 1
    
    #IF NOT IPv6
        else:
            if PACKET_SIZE > 77:
                padding = ''
                for j in range(78, PACKET_SIZE):
                    padding = padding + str(1)
            for i in range(1, NR_OF_PACKETS + 1):
                time.sleep(inter_departure_time)
                snd_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                snd_sock.sendto(str(("%.5f" % time.time(), str('%08d' % i),
                                     padding)).encode("utf-8"), (UDP_DEST_IP, UDP_DEST_PORT))
                packet_count_snd = packet_count_snd + 1
    
    #WAIT FOR ALL PACKETS TO ARRIVE
        packet_wait_time = 3
        time.sleep(packet_wait_time)
        # Perhaps create a custom object where we store the statistics?
        # Or from here save it directly into the database?
    
        PLR = 100 - ((packet_count_rcvd * 100.) / packet_count_snd)
        lost = packet_count_snd - packet_count_rcvd
    
        print('\n')
        print(packet_count_snd,  'packets sent')
        print(packet_count_rcvd,  'packets received')
        print(lost, 'Lost packets')
        print('packet loss ratio = ',  round(PLR, 3),  '%\n')
    
        if (max_delay - min_delay != -100):
            print('max_delay = ', max_delay)
            print('min_delay = ', min_delay)
            print('range   = ', (max_delay - min_delay))
    
    #CALCULATE THE STANDARD DEVIATION
        if rt_delay_array:
            print('std.dev = ', np.std(rt_delay_array))
    
    #CALCULATE JITTER
    # Clear for a clean slate
        jitter = 0
        jitter_2 = 0
    
        # Simple version, no weight
        for rt0, rt1 in zip(rt_delay_array[:-1], rt_delay_array[1:]):
            jitter_2 += np.fabs(rt0 - rt1)
    
        jitter_2 = jitter_2 / (len(rt_delay_array) - 1)
    
    
        # Version used in RFC 1889, also by iperf
        for rt0, rt1 in zip(rt_delay_array[:-1], rt_delay_array[1:]):
            jitter += (np.fabs(rt0 - rt1) - jitter) / 16.
    
        print("jitter = ", jitter)
        print("jitter = ", jitter_2)
    
    #NETWORK STABILITY BASED ON PACKET LOSS AND DELAY, VALUE 0-100
        if packet_count_rcvd == 0:
            pass
        else:
            avg_packet_delay = cumulative_delay / packet_count_rcvd
            print('avg.rtt = ', avg_packet_delay)
    
    
    #CALCULATE STABILITY
    # Calculating MOS
    # http://en.wikipedia.org/wiki/Mean_opinion_score
    #MOS Quality    Impairment
    #5   Excellent  Imperceptible
    #4   Good       Perceptible but not annoying
    #3   Fair       Slightly annoying
    #2   Poor       Annoying
    #1   Bad        Very annoying
    
        EffectiveLatency = avg_packet_delay + jitter * 2 + 10
        if EffectiveLatency < 160:
            R = 93.2 - (EffectiveLatency / 40)
        else:
            R = 93.2 - (EffectiveLatency - 120) / 10
            # Now, let's deduct 2.5 R values per percentage of packet loss
            R = R - (lost * 2.5)
            # Convert the R into an MOS value.(this is a known formula)
        mos = 1 + (0.035) * R + (.000007) * R * (R-60) * (100-R)
    
        print("MOS: ", mos)
    
        post = {
            #"timestamp" : int(time.time()),
        #Not needed since first 4bits of _id is timestamp
            "stability" : mos,
            "position"  : False # Position appended here
        }
    
        DBTableStability.insert(post);
    
    
    #START THE THREADS FOR SENDER AND RECEIVER
    if __name__ == "__main__":
        receiver_thread = Thread(target=udp_client_receive,
                                 args=(UDP_RECEIVE_IP, UDP_RECEIVE_PORT))
        receiver_thread.daemon = True
        receiver_thread.start()
        time.sleep(1)
        while threading.activeCount() <= 2:
    
            # Set the count of the received packets to 0,
            # since the listener thread runs continously
            packet_count_rcvd = 0
            packet_count_snd = 0
    
            sender_thread = Thread(target=udp_client_send,
                                args=(UDP_DEST_IP,  UDP_DEST_PORT,
                                        PACKET_SIZE,  NR_OF_PACKETS,
                                        PACKETS_PER_SEC))
            sender_thread.start()
            while sender_thread.is_alive():
                time.sleep(1)
    
            # Measurement done, store data and then move on
    
    
    
    # While testing, end after one iteration
            sys.exit()