2017-07-16 4 views
0

Ich versuche, Ethernet-Frames über eine Gigabit-Verbindung mit Python zu senden. Daher habe ich diesen Code verwendet:Geschwindigkeit von Socket anpassen

while (package_count < packets): 
    package_count += 1 
    s.send(eth_header+eth_payload) 
    sleep(delay) 

Der Sockel ist zuvor geöffnet. Die Größe eines Frames (eth_header + eth_payload) beträgt 1500 Byte. Um die volle Gigabit-Verbindung zu verwenden, wäre die Verzögerungszeit weit von der minimalen Verzögerungszeit von einigen Millisekunden entfernt. Irgendeine Idee, wie man die Geschwindigkeit des Sendens von Daten unter Verwendung der vollen Gigabit über Sockets in Python steuert?

+0

Verwenden Sie TCP oder UDP? Steckdosen sperren oder nicht sperrend? Was passiert, wenn Sie den Befehl sleep() vollständig entfernen? –

+0

Ich verwende rohe Ethernet-Frames mit SOCK_RAW (überprüft mit wireshark). Wenn ich den Schlaf lösche, bekomme ich volle Geschwindigkeit - aber ich möchte die Geschwindigkeit steuern, die ich sende – who93

+1

Sie können sowohl die Verzögerung als auch die Anzahl der eth-Chunks steuern, um die ungefähre Bandbreite zu erreichen. – zwer

Antwort

0

Es gibt keine explizite Möglichkeit, Sendrate zu steuern; Sie müssen es selbst durch sleep() für die entsprechende Zeit tun. Die Berechnung des geeigneten Wertes für die Übergabe in den Schlafmodus() ist der einzige schwierige Teil. Ich tue es, indem ich einen Zähler der Anzahl der Bytes halte, die bisher gesendet wurden, und subtrahiere von diesem Zähler die Anzahl der Bytes, die in der verstrichenen Zeit gesendet werden sollten. Auf diese Weise weiß ich zu jeder Zeit, wie viele Bytes ich vor dem Zeitplan bin, was sich direkt in die Anzahl der Sekunden einstellt, die ich vor dem Zeitplan habe, also wie lange ich schlafen sollte, um zurück zu sein "nach Plan".

Beispielcode ist unten; Es sendet UDP-Pakete statt Rohdaten, aber die Logik ist die gleiche.

import socket 
import time 

# We'll limit ourself to a 40KB/sec maximum send rate 
maxSendRateBytesPerSecond = (40*1024) 

def ConvertSecondsToBytes(numSeconds): 
    return numSeconds*maxSendRateBytesPerSecond 

def ConvertBytesToSeconds(numBytes): 
    return float(numBytes)/maxSendRateBytesPerSecond 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.connect(('127.0.0.1', 8888)) 

# We'll add to this tally as we send() bytes, and subtract from 
# at the schedule specified by (maxSendRateBytesPerSecond) 
bytesAheadOfSchedule = 0 

# Dummy data buffer, just for testing 
dataBuf = bytearray(1024) 

prevTime = None 

while True: 
    now = time.time() 
    if (prevTime != None): 
     bytesAheadOfSchedule -= ConvertSecondsToBytes(now-prevTime) 
    prevTime = now 

    numBytesSent = sock.send(dataBuf) 
    if (numBytesSent > 0): 
     bytesAheadOfSchedule += numBytesSent 
     if (bytesAheadOfSchedule > 0): 
     time.sleep(ConvertBytesToSeconds(bytesAheadOfSchedule)) 
    else: 
     print "Error sending data, exiting!" 
     break 
+0

danke für deine antwort. Ich werde das in einer vereinfachten Form versuchen, aber der Schlafbefehl arbeitet nur zuverlässig für ungefähr 10ms, für Gigabit-Geschwindigkeit brauche ich weniger als 1ms. Ich habe es jetzt in C implementiert und arbeite perfekt! – who93