2013-02-07 54 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