Sending File Over Python Socket - Hanging at socket.sendall -


i've written thought simple script download files on network python sockets, server hangs on socket.sendall on server side. can file want once, subsequent calls senddata cause crash.

after looking bit more, i'm sure it's how i'm packing header data, meaning may low-level issue beyond ken.

for context: 'master' code running on x86 computer, while 'slave' code running on raspberry pi 0 (arm).

the header's defined in code, here's overview:

  • file length , length of filename bundled 8-byte header of 2 uints.
  • filename , first chunk of (h264 video) data bundled 1kb initial send.
  • the server sends further data in 1kb chunks until it's sent whole file.

i'm pretty puzzled why doesn't work seems routine bit of code.

slave (server)

#takes filename , sends data connected socket def senddata(filename,socket):     try:         filehandle = open(filename,'rb')     except ioerror:         socket.sendall('abort')         print 'file ' +filename+ ' not found; not sending...'     else:         #writes 8 byte header consisting of:         #length of file (including filename) in kb (4b)         #length of filename (4b)         numbytes = struct.pack("<i",math.ceil((os.stat(filename).st_size + len(filename)) / 1024))         #amount of kb (1024) receive, written 4-byte integer         filenamebytes = struct.pack("<i",len(filename))         print 'sending '+filename+'...'         socket.sendall(numbytes + filenamebytes)         data = filename + filehandle.read(1024 - len(filename))         while true:             socket.sendall(data)             data = filehandle.read(1024)             if not data:                 break         filehandle.close()         print 'send complete.' 

master (client)

def receivedownload(socket):     #gets header     data = socket.recv(8)     if data != 'abort':         filekb = struct.unpack("<i",data[:4])[0]#endianness may affecting data transfer         filenamebytes = struct.unpack("<i",data[4:])[0]         data = socket.recv(1024)         filename = data[:filenamebytes]         curkb = 1         print 'getting '+filename+"..."         writeto = open('./footage/'+filename,'wb')         while curkb <= filekb:             print '\r' + str(curkb) + "/" + str(filekb),             sys.stdout.flush()             writeto.write(data)             data = socket.recv(1024)             curkb += 1         writeto.close()         print 'download of '+filename+' successful.'     else:         print 'download failed.' 

i solved problem myself advice jasonharper.

by switching out code measuring in kb more normal code worked in bytes, data socket read. i'm not sure whether original cause of fault down floating point issue or other reason, worked. if need more capacity i'll switch using longs.

for sake of code readability , decrease chance of rounding errors, stopped filename , data being lumped single transmission block.

the original code overengineered when simpler code have done trick.

revised code:

client

def receivedownload(socket):     #gets header     data = socket.recv(8)     if data != 'abort':         fileb = struct.unpack("<i",data[:4])[0]#endianness may affecting data transfer         filenamebytes = struct.unpack("<i",data[4:])[0]         data = socket.recv(filenamebytes)         filename = data         curb = 0         print 'getting '+filename+"..."         writeto = open('./footage/'+filename,'wb')         while curb < fileb:             sys.stdout.flush()             data = socket.recv(1024)             writeto.write(data)             curb += len(data)             print '\r' + str(curb) + "/" + str(fileb),         writeto.close()         print 'download of '+filename+' successful.'     else:         print 'download failed.' 

server

def senddata(filename,socket):     try:         filehandle = open(filename,'rb')     except ioerror:         socket.sendall('abort')         print 'file ' +filename+ ' not found; not sending...'     else:         #writes 8 byte header consisting of:         #length of file in kb (4b)         #length of filename (4b)         numbytes = struct.pack("<i",math.ceil(os.stat(filename).st_size))         #amount of kb (1024) receive, written 4-byte integer         filenamebytes = struct.pack("<i",len(filename))         print 'sending '+filename+'...'         socket.sendall(numbytes + filenamebytes)         data = filename         socket.sendall(data)         while true:             data = filehandle.read(1024)             socket.sendall(data)             if not data:                 break         filehandle.close()         print 'send complete.' 

Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -