2013-02-07 79 views
3

我试图用Python语言编写的程序可以在文件夹中通过套接字传输多个文件,我有以下的代码到目前为止的Python在TCP多个文件传输插座

客户:

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

服务器:

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) 

上面的代码进入一个无限循环,这点我明白,这是因为在if cmd == 'done'部分continue语句的,我不知道为什么它是做日在?我的意思是它从来没有从客户端得到完成的消息,任何人都可以请帮我修复代码?

+0

你的循环将终止在“结束”消息,而不是“完成”的消息。 –

+0

传送所有文件后,我正在发送结束消息。而且,它不会像原样复制文件,它会为第一个文件本身保留一个循环。 – hld619

+0

由于读取是以块的形式完成的,因此只有第一个命令将在块的开始处。其他命令(get,done,end)将位于同一块或下一块内。应该更聪明地分析收到的数据。 – Ante

回答

1

因为命令和文件名是分开的行,所以最好通过行解析接收到的数据。块数据的最后部分不必以\n完成,所以它必须与下一个接收到的数据块合并。

这是(未测试)实施解析的由线接收的数据:

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

Ante,我做了所需的更改,它对于较小的文件很有魅力,但我试图传输更大的文件(256KB文本文件,所有随机数字没有新行),它不识别文件之间的新行,它只是将一切写入一个大文件并进入一个无限循环,你能告诉我它可能出错的地方特别针对大文件吗? – hld619

+0

我不知道:-)命令和文件名是'short',所以如果数据太长可能会帮助解决将数据写入文件的问题。我将修改上面的代码。 – Ante