I am trying to write a program in python to transfer multiple files in a folder over a socket, I have the following code so far
Client:
def uploadFiles(folder,dcip,PORT,filetype):
os.chdir(folder)
dirList = os.listdir(folder)
print dirList
ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print PORT
ms.connect((dcip, int(PORT)))
for fname in dirList:
if fname.endswith(str(filetype)):
cmd = 'get\n%s\n' % (fname)
ms.sendall(cmd)
f = open(fname,'rb')
data = f.read()
f.close()
print data
r = ms.recv(2)
ms.sendall(data)
ms.sendall('done\n%s\n' %(fname))
ms.sendall('end\n\n')
ms.close()
Server:
import socket,os
listener_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener_socket.bind(('',33234))
filename = ''
while 1:
listener_socket.listen(100)
connection,address_client = listener_socket.accept()
if not os.path.exists(str(address_client[0])):
os.makedirs(str(address_client[0]))
currdir = os.getcwd()
os.chdir('./'+str(address_client[0]))
while(1):
data = connection.recv(4096)
cmd = data[:data.find('\n')]
if cmd == 'get':
x,filename,x = data.split('\n',2)
connection.sendall('ok')
f = open(filename,'wb')
if cmd == 'done':
continue
f.write(data)
if cmd == 'end':
connection.close()
break
os.chdir(currdir)
The above code goes into an infinite loop, which I do understand that it is because of the continue statement in the if cmd == 'done'
part, I wonder why it is doing that? I mean it never gets the done message from the client, can anyone please help me fix the code?
Because commands and filenames are in separate lines, it is best to parse received data by lines. Last part of block data doesn't have to finish with a \n
, so it has to be merged with next received data block.
This is (not tested) implementation of parsing received data by lines:
data = '' # contains last line of a read block if it didn't finish with \n
in_get, in_done, reading_file, ended = False, False, False, False
while not ended:
if len(data) > 100: # < update
f.write( data ) # <
data = '' # <
data += connection.recv(4096)
i = data.find('\n')
while i >= 0 and not ended:
line = data[:i]
data = data[i+1:]
if in_get:
filename = line
reading_file = True
f = open(filename,'wb')
in_get = False
elif in_done:
if line != filename: # done inside file content
f.write( 'done\n' + line + '\n' )
else:
f.close()
reading_file = False
in_done = False
else:
if line == 'get' and not reading_file:
in_get = True
elif line == 'done':
in_done = True
elif line == 'end' and not reading_file:
ended = True
break;
else:
f.write( line + '\n' )
i = data.find('\n')