Frage

Ich habe zwei Programme, sendfile.py und recvfile.py, die angeblich zu interagieren, um eine Datei über das Netzwerk zu senden. Sie kommunizieren über TCP-Sockets. Die Kommunikation soll so etwas gehen:

sender =====filename=====> receiver

sender <===== 'ok' ======= receiver
               or
sender <===== 'no' ======= receiver

if ok:
sender ====== file ======> receiver 

Ich habe

Der Sender und Empfänger-Code ist hier:

Sender:

import sys
from jmm_sockets import *

if len(sys.argv) != 4:
    print "Usage:", sys.argv[0], "<host> <port> <filename>"
    sys.exit(1)

s = getClientSocket(sys.argv[1], int(sys.argv[2]))

try:
    f = open(sys.argv[3])
except IOError, msg:
    print "couldn't open file"
    sys.exit(1)

# send filename
s.send(sys.argv[3])

# receive 'ok'
buffer = None
response = str()
while 1:
    buffer = s.recv(1)
    if buffer == '':
        break
    else:
        response = response + buffer
if response == 'ok':
    print 'receiver acknowledged receipt of filename'
    # send file
    s.send(f.read())
elif response == 'no':
    print "receiver doesn't want the file"

# cleanup
f.close()
s.close()

Empfänger:

from jmm_sockets import *

s = getServerSocket(None, 16001)
conn, addr = s.accept()


buffer = None
filename = str()

# receive filename
while 1:
    buffer = conn.recv(1)
    if buffer == '':
        break
    else:
        filename = filename + buffer
print "sender wants to send", filename, "is that ok?"
user_choice = raw_input("ok/no: ")

if user_choice == 'ok':
    # send ok
    conn.send('ok')
    #receive file
    data = str()
    while 1:
        buffer = conn.recv(1)
        if buffer=='':
            break
        else:
            data = data + buffer
            print data
else:
    conn.send('no')
conn.close()

Ich bin sicher, bin ich etwas fehlt hier in der Art eines Deadlocks, aber nicht wissen, was es ist.

War es hilfreich?

Lösung

TCP ist ein Streaming-Protokoll. Es hat kein Konzept von Nachrichtengrenzen. Für einen blockierenden Socket, recv (n) wird eine Rückkehr leere Zeichenfolge nur dann, wenn der Absender die Buchse oder explizit Abschaltung aufgerufen geschlossen (SHUT_WR). Andernfalls kann er eine Zeichenfolge aus einer Rückkehr zu n in der Länge Bytes und wird blockiert, bis es mindestens ein Byte zurückgeben muß.

Es ist an Ihnen, ein Protokoll zu entwerfen, um zu bestimmen, wenn Sie eine vollständige Nachricht haben. Einige Möglichkeiten sind:

  1. Verwenden Sie eine feste Länge Nachricht.
  2. Senden eine Nachricht mit fester Länge anzeigt, die Gesamtnachrichtenlänge, gefolgt von dem variablen Teil der Nachricht.
  3. Senden Sie die Nachricht, durch eine eindeutige Beendigungsnachricht gefolgt, die nie in der Nachricht auftreten.

Ein weiteres Problem kann man konfrontiert ist, dass senden ( ) nicht senden alle Daten garantiert. Der Rückgabewert gibt an, wie viele Bytes tatsächlich gesendet, und es liegt in der Verantwortung des Absenders mit der verbleibenden Nachricht Aufruf send zu halten Bytes, bis sie alle gesendet werden. Sie können vielmehr die Verwendung sendall () -Methode.

Andere Tipps

Mit blockierende Sockets, die Standardeinstellung sind und ich gehe davon sind, was Sie verwenden (kann nicht sicher sein, da Sie ein mysteriöses Modul jmm_sockets verwenden), ist die recv Methode blockiert - es wird kein leeres Rück Zeichenfolge, wenn es „nichts mehr für den Moment zurückzukehren“, wie Sie davon ausgehen, scheinen.

Sie könnten arbeiten, um diesen, zum Beispiel durch ein explizites Abschlusszeichen zu senden (das darf auf keinen Fall in einem Dateinamen auftreten), z.B. '\xff', nach der eigentlichen Zeichenfolge Sie senden möchten, und für sie am anderen Ende als Anzeige warten, dass alle die Zeichenfolge nun empfangen wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top