2016-05-15 279 views
1

我試圖通過套接字傳輸文件,如果我立即關閉連接立即關閉連接 現在我想繼續發送命令到服務器上傳完成後,但服務器只是忽略他們,並認爲有更多的線路來對文件Python通過套接字傳輸文件

這裏是我到目前爲止的代碼 客戶:

def client_sender(): 
    global upload 
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    try: 
     print target 
     print port 
     client.connect((target, port)) 

     if upload: 
      with open(upload_destination, "rb") as f: 
       for line in f: 
        client.send(line) 
      f.close() 
      client.send("DONE\r\n") 
      upload = False 

     print client.recv(1024) 
     buffer = "" 
     buffer = sys.stdin.read() 
#... some code for sending commands and receiving a response 

服務器:

def handle_client(client_socket): 
    global upload 
    print "Client connected" 
    if upload: 
     file_buffer = "" 
     while True: 
      data = client_socket.recv(1024) 
      if data.rstrip() == "DONE": 
       break 
      file_buffer += data 
     try: 
      file_descriptor = open(upload_destination, 'wb') 
      file_descriptor.write(file_buffer) 
      file_descriptor.close() 

      client_socket.send("Successfully placed the file in %s" %upload_destination) 
     except: 
      client_socket.send("Failed writing to the file") 

     upload = False 
#... same as client, just some more code for commands 
+1

如果文件包含「DONE」,會發生什麼情況會很有趣。 – mhawke

+0

這是爲了傳輸我編寫的已編譯的C程序,所以沒有辦法可以適得其反 – Aginu

回答

3

嘗試打印data的值後data = client_socket.recv(1024) 您可能會看到類似於:"endofthefile\nDONE\r\n"

所以當你運行rstrip時,你會得到:"endofthefile\nDONE",這不等於"DONE"

你應該重寫你的while循環是這樣的:

while True: 
     data = client_socket.recv(1024) 
     for line in data.split('\n'): 
      if data.rstrip() == "DONE": 
       break 
      file_buffer += line + '\n' 

你也可以使用該客戶端上的宣佈結束:client.sendall("DONE\r\n")sendall立即刷新客戶端的緩衝區,而不是等待更多的數據在同一個數據包中發送。


偏離主題,但我建議你改變你的協議。如果文件包含DONE行,它將不起作用;這樣在服務器上分割線是不夠的。 更好的方法是讓客戶端公佈文件的大小,然後繼續發送它,以便服務器知道何時停止閱讀。

+0

我試過了你的代碼示例,但它並不能真正解決問題 但是,你的建議是改變協議的聲音很不錯,所以我會試一試!非常感謝你! – Aginu