Ich schreibe eine Funktion zum Lesen aus dem Socket und zum Zurückgeben der genauen Datengröße. Und ich dachte an Codes wie:

whlie len(buf) < required:
    buf += socket.recv(required - len(buf))

return buf

Aber ich denke, dies könnte einige CPU-Ressourcen verschwenden (nicht sicher). Ich suche nach einem Systemaufruf oder etwas, um die genaue Datenmenge vom Socket zurückzugeben, und es könnte blockiert werden, bis die erforderliche Größe empfangen wird.

1
can. 7 Juli 2013 im 06:29

3 Antworten

Beste Antwort

Dadurch werden keine CPU-Ressourcen verschwendet.

sock.recv blockiert bis mindestens eine Byte ist verfügbar (kann jedoch mehrere Bytes puffern und zurückgeben, wenn sie verfügbar sind), sodass Ihre Anwendung nicht in eine Besetztschleife eintritt.

Im Allgemeinen sollte die Pufferlänge des Aufrufs sock.recv betragen hat nichts mit der Länge der Nachricht zu tun, die Sie abrufen möchten.


Die Verkettung von Zeichenfolgen ist für Ihren Puffer jedoch nicht effizient.

Möglicherweise möchten Sie Folgendes verwenden:

  • Eine Liste und ''.join() (b''.join() bei Verwendung von Python 3)
  • Die Module StringIO und cStringIO (oder io.BytesIO, wenn Python 3 verwendet wird).
  • Verwenden von sock.recv_into und {{X1} } / bytesIO.
2
Thomas Orozco 7 Juli 2013 im 18:38

Siehe mein Beispiel für das Python 2.x-Socket-Modul. Verwenden Sie memoryview() und recv_into(),

def readReliably(s,n):
    buf = bytearray(n)
    view = memoryview(buf)
    sz = s.recv_into(view,n)
    return sz,buf

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...
sz,buf = io.readReliably(s,4)
a = struct.unpack("4B",buf)
print repr(a)

Die Größe des von readReliably() zurückgegebenen Puffers kann größer als n sein. Vergessen Sie es nicht.

0
Alexander Lubyagin 31 März 2019 im 23:47

Wenn Sie die Standard-Socket-Bibliothek verwenden, können Sie Folgendes verwenden.

import socket
host, port = "localhost", 8000
num_bytes  = 5000

sock = socket.socket()
sock.connect((host, port))
while True:
    data = sock.recv(num_bytes)
    handle(data)

Sie können sich die möglichen Parameter hier ansehen Dokumentation zu socket.recv

0
Cameron Wrigley 7 Juli 2013 im 02:57