Transferring multiple Python files over TCP sockets

I am trying to write a python program to transfer multiple files to a folder via socket, I have the following code so far

Customer:

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 understand because because of the continue statement in the part if cmd == 'done'

I'm wondering why it does this? I mean it never gets a message from the client, can anyone help me fix the code?

+3


source to share


1 answer


Since the commands and filenames are on separate lines, it is best to parse the resulting data line by line. The last piece of block data must not end with \n

, so it must be combined with the next received block of data.

This is an (untested) implementation of parsing the received data line by line:



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

      

+1


source







All Articles