Vorbereitung Versuchstag 4 fertig.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
Versuch\ 3/.venv/
|
Versuch\ 3/.venv/
|
||||||
|
*.pcap
|
||||||
|
|||||||
92
README.md
92
README.md
@@ -110,19 +110,79 @@ ntpq time1.rrzn.uni-hannover.de
|
|||||||
|
|
||||||
### Streaming über das drahtgebundene Netz
|
### Streaming über das drahtgebundene Netz
|
||||||
|
|
||||||
- Mittelwert = sum(i)/n = x
|
- Segmentation offloading ausschalten
|
||||||
- Varianz = sum((i - x)^2)/n
|
|
||||||
- Std.Abw = root(Varianz)
|
```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:
|
- Eingestellte Bitrate:
|
||||||
- Tatsächlich gesendete Bitrate:
|
- Tatsächlich gesendete Bitrate:
|
||||||
|
|
||||||
### Streaming über WLAN
|
### Streaming über WLAN
|
||||||
|
|
||||||
|
- default route über WLan einrichten
|
||||||
|
|
||||||
#### Plot TCP
|
#### Plot TCP
|
||||||
|
|
||||||
|
- Stream für 60s mitschneiden und auswerten
|
||||||
|
- Wie vorher schon nur über WLan
|
||||||
|
- Plot der Pakete
|
||||||
|
- OWDS
|
||||||
|
|
||||||
|
- Mittelwert:
|
||||||
|
- Varianz:
|
||||||
|
- Standardabweichung:
|
||||||
|
|
||||||
#### Plot UDP
|
#### Plot UDP
|
||||||
|
|
||||||
|
- Mittelwert:
|
||||||
|
- Varianz:
|
||||||
|
- Standardabweichung:
|
||||||
|
|
||||||
|
|
||||||
|
- Was ist besser?
|
||||||
|
|
||||||
#### Mittelwert und Standardabweichung der OWDs
|
#### Mittelwert und Standardabweichung der OWDs
|
||||||
|
|
||||||
- TCP:
|
- 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.
|
- 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?
|
||||||
|
|||||||
47
Versuchstag-3/calc-owd.py
Executable file
47
Versuchstag-3/calc-owd.py
Executable file
@@ -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))
|
||||||
62
Versuchstag-3/plot-pcap.py
Executable file
62
Versuchstag-3/plot-pcap.py
Executable file
@@ -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)
|
||||||
60
Versuchstag-3/simple-client.py
Executable file
60
Versuchstag-3/simple-client.py
Executable file
@@ -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)")
|
||||||
63
Versuchstag-3/simple-server.py
Executable file
63
Versuchstag-3/simple-server.py
Executable file
@@ -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)")
|
||||||
Reference in New Issue
Block a user