Wootywoots
Wootywoots

Reputation: 15

Python sending a file over sockets

I am trying to write a script that requires files to be sent from server to clients and am having issues with the files being completely sent when the destination is not the local host. So when the server and client are on different machines the client seems to receive the file faster then the server is sending it and stops receiving early. An example is if I try to send a 200 MB file over the client stops receiving it around usually around 180 MB.

Here are the portions of the script that send and receive files.

send file

def t_handle(client, address, s):
file_size = str(os.stat("path to file to send").st_size)
print file_size
client.send(file_size)
work_file = open("path to fil to send", "rb")
print "sending file"
file_size = int(file_size)
while file_size > 0:
    buffer = work_file.read(1024)
    client.send(buffer)
    file_size -= 1024
    print file_size
print "done"

Receive file

def main():
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.settimeout(90)
server.connect((host, port))
file_size = int(server.recv(1024))
print "receiving file"
file_size = int(file_size)
print file_size
f = open("test_output.mkv", "wb+")
while file_size > 0:
    work_file = server.recv(1024)
    f.write(work_file)
    file_size -= 1024
    print file_size
f.close()
print "done"
return 0

Any help would be greatly appreciated.

Upvotes: 1

Views: 3410

Answers (1)

bgporter
bgporter

Reputation: 36504

The argument to socket.recv() is the maximum number of bytes that the call will return, and there's no guarantee that you'll actually get that many on any given call:

while file_size > 0:
    work_file = server.recv(1024)
    f.write(work_file)
    file_size -= 1024
    print file_size

If you receive fewer than 1024 bytes on each call, yet subtract that many from your target byte count, your code will act as if it's complete before it actually is.

Try modifying it to something like:

while file_size > 0:
    work_file = server.recv(1024)
    f.write(work_file)
    # subtract the actual number of bytes received
    file_size -= len(work_file)
    print file_size

Upvotes: 3

Related Questions