2016-09-23 22 views
2

收到到目前爲止,我可以將文件發送到我的「文件服務器」,並從那裏以及檢索文件。但我不能同時做這兩件事。我必須評論其他線程的其中一個工作。正如你將在我的代碼中看到的那樣。試圖建立一個原油發送/ TCP通過在Python

服務器代碼

from socket import * 
import threading 
import os 

# Send file function 
def SendFile (name, sock): 
filename = sock.recv(1024)  
    if os.path.isfile(filename):  
    sock.send("EXISTS " + str(os.path.getsize(filename))) 
    userResponse = sock.recv(1024)  
    if userResponse[:2] == 'OK':   
     with open(filename, 'rb') as f: 
      bytesToSend = f.read(1024) 
      sock.send(bytesToSend) 
      while bytesToSend != "": 
       bytesToSend = f.read(1024) 
       sock.send(bytesToSend) 
else:         
    sock.send('ERROR') 

sock.close() 

def RetrFile (name, sock): 
    filename = sock.recv(1024)  
    data = sock.recv(1024)      
    if data[:6] == 'EXISTS':    
     filesize = long(data[6:])  
     sock.send('OK') 
     f = open('new_' + filename, 'wb')  
     data = sock.recv(1024) 
     totalRecieved = len(data)    
     f.write(data) 
     while totalRecieved < filesize:   
     data = sock.recv(1024) 
     totalRecieved += len(data) 
     f.write(data) 

sock.close() 



myHost = ''        
myPort = 7005       

s = socket(AF_INET, SOCK_STREAM)  
s.bind((myHost, myPort))    

s.listen(5) 

print("Server Started.") 

while True:        

connection, address = s.accept() 
print("Client Connection at:", address) 

# u = threading.Thread(target=RetrFile, args=("retrThread", connection)) 
t = threading.Thread(target=SendFile, args=("sendThread", connection))  
# u.start() 
t.start() 


s.close() 

客戶端代碼

from socket import * 
import sys 
import os 

servHost = ''       
servPort = 7005       

s = socket(AF_INET, SOCK_STREAM)   
s.connect((servHost, servPort))   

decision = raw_input("do you want to send or retrieve a file?(send/retrieve): ") 

if decision == "retrieve" or decision == "Retrieve": 
    filename = raw_input("Filename of file you want to retrieve from server: ")  # ask user for filename 
    if filename != "q":      
    s.send(filename)      
    data = s.recv(1024)     
    if data[:6] == 'EXISTS':   
     filesize = long(data[6:])  
     message = raw_input("File Exists, " + str(filesize)+"Bytes, download?: Y/N -> ")  

     if message == "Y" or message == "y": 
      s.send('OK') 
      f = open('new_' + filename, 'wb')  
      data = s.recv(1024)      
      totalRecieved = len(data)    
      f.write(data) 
      while totalRecieved < filesize:   
       data = s.recv(1024) 
       totalRecieved += len(data) 
       f.write(data) 
       print("{0: .2f}".format((totalRecieved/float(filesize))*100)) + "% Done" # print % of download progress 

      print("Download Done!") 

    else: 
     print("File does not exist!") 
s.close() 

elif decision == "send" or decision == "Send": 
filename = raw_input("Filename of file you want to send to server: ") 
if filename != "q": 
    s.send(filename)      
    if os.path.isfile(filename):  
     s.send("EXISTS " + str(os.path.getsize(filename))) 
     userResponse = s.recv(1024)  
     if userResponse[:2] == 'OK': 
      with open(filename, 'rb') as f: 
       bytesToSend = f.read(1024) 
       s.send(bytesToSend) 
       while bytesToSend != "":  
        bytesToSend = f.read(1024) 
        s.send(bytesToSend) 
    else:         
     s.send('ERROR') 

s.close() 


s.close() 

我還是新的節目,所以這對我來說是相當艱難。總而言之,我只是想弄清楚如何發送和接收文件,而不必在我的SERVER CODE中註釋掉底線。

請和謝謝!

+0

這不是FTP,對不對?這是你的自定義協議。 –

+0

對不起,如果我的術語關閉,可能不是FTP。 –

+0

如果您有兩個不同線程試圖同時從同一個套接字接收數據,您會發生什麼? – immibis

回答

0

剛纔if語句發送真或假,這將決定執行哪個線程。

0

在服務器端,你想用你的兩個線程t和u相同的連接。

我想,如果你聽了服務器在您while True:循環另一個連接,它可能工作你開始你的第一個線程之後。

我總是使用更高層次的socketserver模塊(Python Doc on socketserver),它本身也支持線程處理。我建議檢查一下!

順便說一句,因爲你做了很多的if (x == 'r' or x == 'R'):你可以只是做if x.lower() == 'r'

+0

所以看起來我能夠通過創建一個新的連接來使兩個線程都能正常工作,正如人們在這裏所建議的那樣。無論如何,使我的線程可以採取第二或第一個連接值? –

+0

我不知道我理解你的問題,但我猜你希望每個線程都能夠檢索和發送?在這種情況下,我認爲將'SendFile'和'RetrFile'函數統一到* one *函數就足夠了,並且用'threading.Thread(target = UnifiedFunction)'將它們提供給兩個線程。因此,將兩個函數重寫爲一個,在'filename = sock.recv(1024)'後檢查文件是否存在,如果存在,發送它,如果不存在,繼續'data = sock.recv(1024) '並檢索它。 – krork