Question

J'ai deux programmes, sendfile.py et recvfile.py qui sont censés interagir pour envoyer un fichier à travers le réseau. Ils communiquent sur des sockets TCP. La communication est censé aller quelque chose comme ceci:

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

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

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

J'ai

L'expéditeur et le code de récepteur est ici:

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()

Récepteur:

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()

Je suis sûr que je manque quelque chose ici dans le genre d'une impasse, mais je ne sais pas ce qu'elle est.

Était-ce utile?

La solution

TCP est un protocole de diffusion en continu. Il n'a pas de concept de frontières de message. Pour une douille de blocage, recv (n) retourne un chaîne de longueur zéro uniquement lorsque l'expéditeur a fermé la douille ou appelée explicitement arrêt (SHUT_WR). Sinon, il peut renvoyer une chaîne de un à n octets de longueur, et permet de bloquer jusqu'à ce qu'elle comporte au moins un octet de retour.

Il vous appartient de concevoir un protocole pour déterminer si vous avez un message complet. Quelques voies sont:

  1. Utilisation d'un message de longueur fixe.
  2. Envoyer un message de longueur fixe indiquant la longueur totale du message, suivies par la partie variable du message.
  3. Envoyer le message, suivi d'un message de terminaison unique qui ne se produira jamais dans le message.

Une autre question vous pouvez faire face est que ( ) n'est pas garanti d'envoyer toutes les données. La valeur de retour indique combien d'octets ont été effectivement envoyés, et il est de la responsabilité de continuer à appeler envoyer le message octets restants jusqu'à ce qu'ils soient tous envoyés de l'expéditeur. Vous pouvez plutôt utiliser la méthode () Sendall .

Autres conseils

Avec des prises de blocage, qui sont la valeur par défaut et je suppose que vous ce que vous utilisez (ne peut pas être sûr puisque vous utilisez un module mystérieux jmm_sockets), la méthode de blocage recv est - il ne reviendra pas un vide chaîne quand il a « rien de plus à revenir pour le moment », comme vous semblez le supposer.

Vous pouvez travailler autour de cela, par exemple, en envoyant un caractère de terminaison explicite (qui ne doit jamais se produire dans un nom de fichier), par exemple '\xff', après la chaîne réelle que vous voulez envoyer, et d'attendre au moment de l'autre extrémité comme l'indication que toute la chaîne a été reçue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top