| @@ -1 +1,2 @@ | |||
| Versuch\ 3/.venv/ | |||
| *.pcap | |||
| @@ -110,19 +110,79 @@ ntpq time1.rrzn.uni-hannover.de | |||
| ### Streaming über das drahtgebundene Netz | |||
| - Mittelwert = sum(i)/n = x | |||
| - Varianz = sum((i - x)^2)/n | |||
| - Std.Abw = root(Varianz) | |||
| - Segmentation offloading ausschalten | |||
| ```bash | |||
| ethtool -K <interface> tso off | |||
| ``` | |||
| - tcpdump starten auf Client und Server | |||
| - als root | |||
| - Auf dem Client | |||
| ```bash | |||
| tcpdump -i <interface> tcp and port 1337 and dst <server-ip> -r <file-name.pcap> | |||
| ``` | |||
| - Auf dem Server | |||
| ```bash | |||
| tcpdump -i <interface> tcp and port 1337 and src <client-ip> -r <file-name.pcap> | |||
| ``` | |||
| - simple-server.py und simple-client.py verwenden | |||
| - Client auf dem PI | |||
| - Server auf dem Laptop | |||
| ```bash | |||
| ./simple-server.py -a <IP> --tcp | |||
| ./simple-client.py -s <Server-IP> --tcp | |||
| ``` | |||
| - Commulative arrival function für Server und Client berechnen und ploten | |||
| - Für später schon Bitraten notieren | |||
| ```bash | |||
| ./plot-pcap.py --client <pcap> --server <pcap> | |||
| ``` | |||
| - OWDs berechnen | |||
| ```bash | |||
| ./calc-owd.py --client <pcap> --server <pcap> | |||
| ``` | |||
| - Mittelwert: | |||
| - Varianz: | |||
| - Standardabweichung: | |||
| - Eingestellte Bitrate: | |||
| - Tatsächlich gesendete Bitrate: | |||
| ### Streaming über WLAN | |||
| - default route über WLan einrichten | |||
| #### Plot TCP | |||
| - Stream für 60s mitschneiden und auswerten | |||
| - Wie vorher schon nur über WLan | |||
| - Plot der Pakete | |||
| - OWDS | |||
| - Mittelwert: | |||
| - Varianz: | |||
| - Standardabweichung: | |||
| #### Plot UDP | |||
| - Mittelwert: | |||
| - Varianz: | |||
| - Standardabweichung: | |||
| - Was ist besser? | |||
| #### Mittelwert und Standardabweichung der OWDs | |||
| - TCP: | |||
| @@ -134,3 +194,29 @@ ntpq time1.rrzn.uni-hannover.de | |||
| - Um OWDs mit UDP genauer zu berechnen müsste die Reihenfolge der Pakete beachtet werden und die Uhren von Client und Server genaustens synkronisiert werden. | |||
| #### Verschiedene Bitraten | |||
| - Hier wieder OWDs messen | |||
| - Für LAN | |||
| - Für WLAN | |||
| #### Verschiedene Parameter raspivid | |||
| - Hier wieder OWDs messen | |||
| #### Verschiedene Puffergrößen | |||
| - Einmal mit 10Byte und 1400 Byte (WLan MTU) | |||
| - Was passiert, wenn die Puffergröße größer als tie MTU | |||
| - Fragmentierung, mehr Overhead | |||
| - Mit 4000B Puffergröße versuchen | |||
| - Mit Wireshark angucken | |||
| ### Streaming am Fahrzeug | |||
| - Ploten der Pakete in einer Abbildung (wie vorher) | |||
| - Wenn das Modellauto sich stetig vom Router entfernt. | |||
| - Wenn das Modellauto den Raum verlässt. | |||
| - Was kann in beiden Fällen beobachtet werden? | |||
| @@ -0,0 +1,47 @@ | |||
| #!/usr/bin/env python | |||
| import argparse | |||
| import os | |||
| import sys | |||
| import math | |||
| from scapy.all import * | |||
| if __name__ == '__main__': | |||
| parser = argparse.ArgumentParser(description='Plot two PCAP files') | |||
| parser.add_argument('--client', metavar='<pcap file name>', help='pcap file to parse', required=True) | |||
| parser.add_argument('--server', metavar='<pcap file name>', help='pcap file to parse', required=True) | |||
| args = parser.parse_args() | |||
| if not os.path.isfile(args.server): | |||
| print('"{}" does not exist'.format(args.server), file=sys.stderr) | |||
| sys.exit(-1) | |||
| if not os.path.isfile(args.client): | |||
| print('"{}" does not exist'.format(args.client), file=sys.stderr) | |||
| sys.exit(-1) | |||
| # calc owd | |||
| packets_send = rdpcap(args.client) | |||
| packets_rec = rdpcap(args.server) | |||
| # check len | |||
| PACKAGES = 4000 | |||
| if (not len(packets_send) >= PACKAGES) or (not len(packets_rec) >= PACKAGES): | |||
| print("Nicht genug Pakete!") | |||
| exit() | |||
| owds = [] | |||
| for i in range(0, PACKAGES): | |||
| owd = packets_rec[i].time - packets_send[i].time | |||
| owds.append(owd) | |||
| mittwelwert = sum(owds) / len(owds) | |||
| varianz = 0 | |||
| for owd in owds: | |||
| varianz = varianz + (owd - mittwelwert)**2 | |||
| varianz = varianz / len(owds) | |||
| stdabw = math.sqrt(varianz) | |||
| print("Mittelwert: " + str(mittwelwert)) | |||
| print("Varianz: " + str(varianz)) | |||
| print("Standardabweichung: " + str(stdabw)) | |||
| @@ -0,0 +1,62 @@ | |||
| #!/usr/bin/env python | |||
| import argparse | |||
| import os | |||
| import sys | |||
| from scapy.all import * | |||
| import matplotlib.pyplot as plt | |||
| def process_pcap(file_name): | |||
| print('Opening {}...'.format(file_name)) | |||
| x_axis_time = [0] | |||
| y_axis_com_data = [0] | |||
| # Get times | |||
| packets = rdpcap(file_name) | |||
| for pkt in packets: | |||
| x_axis_time.append(pkt.time) | |||
| time_start = x_axis_time[1] | |||
| time_end = x_axis_time[-1] | |||
| # format time axis | |||
| for i in range(1, len(x_axis_time)): | |||
| x_axis_time[i] = x_axis_time[i] - time_start | |||
| # get payloads | |||
| pcap_file = RawPcapReader(file_name) | |||
| for (pkt_data, pkt_metadata,) in pcap_file: | |||
| y_axis_com_data.append(y_axis_com_data[-1] + pkt_metadata.wirelen) | |||
| print('{} contains {} packets.\nStart time: {}\tEnd time: {}\t Transfered: {}kB\tDuration: {}'.format(file_name, len(packets), time_start, time_end, (y_axis_com_data[-1] / 8) / 1000, time_end - time_start)) | |||
| bitrate = (y_axis_com_data[-1] / (time_end - time_start)) / 1000000 # MBit/s | |||
| print('Bitrate: ' + str(math.floor(bitrate * 100)/100) + 'MBit/s\n') | |||
| return (x_axis_time, y_axis_com_data) | |||
| if __name__ == '__main__': | |||
| parser = argparse.ArgumentParser(description='Plot two PCAP files') | |||
| parser.add_argument('--client', metavar='<pcap file name>', help='pcap file to parse', required=True) | |||
| parser.add_argument('--server', metavar='<pcap file name>', help='pcap file to parse', required=True) | |||
| args = parser.parse_args() | |||
| file_name1 = args.server | |||
| file_name2 = args.client | |||
| if not os.path.isfile(file_name1): | |||
| print('"{}" does not exist'.format(file_name), file=sys.stderr) | |||
| sys.exit(-1) | |||
| if not os.path.isfile(file_name2): | |||
| print('"{}" does not exist'.format(file_name), file=sys.stderr) | |||
| sys.exit(-1) | |||
| pcap1_x, pcap1_y = process_pcap(file_name1) | |||
| pcap2_x, pcap2_y = process_pcap(file_name2) | |||
| plt.plot(pcap1_x, pcap1_y) | |||
| plt.plot(pcap2_x, pcap2_y, color='green') | |||
| plt.xlabel('Time [ms]') | |||
| plt.ylabel('Transfered Data [bit]') | |||
| plt.legend(["Server (Laptop)", "Client (Pi)"]) | |||
| plt.show() | |||
| sys.exit(0) | |||
| @@ -0,0 +1,60 @@ | |||
| #!/usr/bin/env python | |||
| import socket, argparse, subprocess | |||
| if __name__ == "__main__": | |||
| parser = argparse.ArgumentParser(description='Simple Client') | |||
| parser.add_argument('-p', default=1337, type=int, help='Serverport the server is listen on.') | |||
| parser.add_argument('-s', type=str, required=True, help='IPv4 address of the servers') | |||
| parser.add_argument('--tcp', action='store_true', help='Use TCP.') | |||
| parser.add_argument('--udp', action='store_true', help='Use UDP.') | |||
| args = parser.parse_args() | |||
| if args.udp and args.tcp: | |||
| print("Only one protocol is allowed.") | |||
| exit(1) | |||
| elif not args.udp and not args.tcp: | |||
| print("Specify protocol") | |||
| exit(1) | |||
| BUFFER_SIZE = 1400 | |||
| # IP und Port des Servers | |||
| IP = args.s | |||
| PORT = args.p | |||
| # Unterstützte Addresstypen (IPv4, IPv6, lokale Addressen) | |||
| address_families = (socket.AF_INET, socket.AF_INET6, socket.AF_UNIX) | |||
| # Unterstützte Sockettypen (TCP, UDP, Raw (ohne Typ)) | |||
| socket_types = (socket.SOCK_STREAM, socket.SOCK_DGRAM, socket.SOCK_RAW) | |||
| # Passenden Address- und Sockettyp wählen | |||
| address_family = address_families[0] | |||
| if args.tcp: | |||
| socket_type = socket_types[0] | |||
| else: | |||
| socket_type = socket_types[1] | |||
| # Erstellen eines Sockets (TCP und UDP) | |||
| sock = socket.socket(address_family, socket_type) | |||
| try: | |||
| if args.tcp: | |||
| # Verbinden zu einem Server-Socket (Nur TCP) | |||
| sock.connect((IP,PORT)) | |||
| # raspivid starten | |||
| cmd_raspivid = 'raspivid -t 0 -fps 20 -w 1280 -h 720 -b 2000000 -o -' | |||
| rasprocess = subprocess.Popen(cmd_raspivid,shell=True,stdout=subprocess.PIPE) | |||
| while True: | |||
| # Daten der Größe BUFFER_SIZE aus der Ausgabe von raspivid auslesen | |||
| message = rasprocess.stdout.read(BUFFER_SIZE) | |||
| if args.tcp: | |||
| # TCP | |||
| sock.send(message) | |||
| else: | |||
| # UDP | |||
| sock.sendto(message, (IP, PORT)) | |||
| except KeyboardInterrupt: | |||
| print("Close socket.") | |||
| sock.close() | |||
| print("Exiting through keyboard event (CTRL + C)") | |||
| @@ -0,0 +1,63 @@ | |||
| #!/usr/bin/env python | |||
| import socket, argparse, subprocess | |||
| if __name__ == "__main__": | |||
| parser = argparse.ArgumentParser(description='Simple Server') | |||
| parser.add_argument('-p', default=1337, type=int, help='Serverport the server is listen on.') | |||
| parser.add_argument('-a', type=str, required=True, help='IPv4 address of the servers interface for bind.') | |||
| parser.add_argument('--tcp', action='store_true', help='Use TCP.') | |||
| parser.add_argument('--udp', action='store_true', help='Use UDP.') | |||
| args = parser.parse_args() | |||
| if args.udp and args.tcp: | |||
| print("Only one protocol is allowed.") | |||
| exit(1) | |||
| elif not args.udp and not args.tcp: | |||
| print("Specify protocol") | |||
| exit(1) | |||
| # Port des Servers | |||
| PORT = args.p | |||
| # Lesepuffergröße | |||
| BUFFER_SIZE = 1400 | |||
| # Unterstützte Addresstypen (IPv4, IPv6, lokale Addressen) | |||
| address_families = (socket.AF_INET, socket.AF_INET6, socket.AF_UNIX) | |||
| # Unterstützte Sockettypen (TCP, UDP, Raw (ohne Typ)) | |||
| socket_types = (socket.SOCK_STREAM, socket.SOCK_DGRAM, socket.SOCK_RAW) | |||
| # Passenden Address- und Sockettyp wählen | |||
| address_family = address_families[0] | |||
| if args.tcp: | |||
| socket_type = socket_types[0] | |||
| else: | |||
| socket_type = socket_types[1] | |||
| # Maximale Anzahl der Verbindungen in der Warteschlange | |||
| backlog = 1 | |||
| try: | |||
| # Erstellen eines Socket (TCP und UDP) | |||
| sock = socket.socket(address_family, socket_type) | |||
| sock.bind((args.a, PORT)) | |||
| if args.tcp: | |||
| # Lausche am Socket auf eingehende Verbindungen (Nur TCP) | |||
| sock.listen(backlog) | |||
| clientsocket, address = sock.accept() | |||
| # mplayer starten | |||
| cmd_mplayer = 'mplayer -fps 25 -cache 512 -' | |||
| mprocess = subprocess.Popen(cmd_mplayer, shell=True, stdin=subprocess.PIPE) | |||
| while True: | |||
| # Daten (der Größe BUFFER_SIZE) aus dem Socket holen und ausgeben: | |||
| if args.tcp: | |||
| # TCP: | |||
| data = clientsocket.recv(BUFFER_SIZE) | |||
| else: | |||
| # UDP: | |||
| data, address = sock.recvfrom(BUFFER_SIZE) | |||
| # Die ausgelesenen Daten an mplayer weiterleiten | |||
| mprocess.stdin.write(data) | |||
| except KeyboardInterrupt: | |||
| print("Close socket.") | |||
| sock.close() | |||
| print("Exiting through keyboard event (CTRL + C)") | |||