[英]Sending a file to a server using sockets in Python
主頁顯示我的首頁,上傳應顯示您輸入要與服務器存儲的文件的頁面
def upload():
path_name = raw_input("Enter your file directory")
open_file = open(path_name,'rb').read()
name_split = path_name.split("\\")[-1].split('.')
at = 1
s.send("SAVE-"+username+"\\"+"".join(name_split[:-1])+"."+str(at)+"."+name_split[-1]+"-")
while open_file:
current = open_file[:1024]
print current
open_file = open_file[1024:]
s.send(current)
def mainpage():
global R2
R2=Tk()
gg="white"
g="blue"
R2.geometry('720x720')
R2.title(username + " Dropbox")
R2.resizable(width=False,height=False)
logoutbt= Button(R2,text="Logout",width=10,height=2,bg=g,fg=gg,font="5",relief=RAISED,overrelief=RIDGE,command=deslogout)
upload = Button(R2,text="Upload",width=10,height=2,bg=g,fg=gg,font="5",relief=RAISED,overrelief=RIDGE,command=desupload)
retrieve = Button(R2,text="Retreive",width=10,height=2,bg=g,fg=gg,font="5",relief=RAISED,overrelief=RIDGE,command=desretreive)
logoutbt.place(x = 220,y = 500)
retrieve.place(x = 350,y = 500)
upload.place(x = 480,y = 500)
R2.mainloop()
open(path_name,'rb').close()
現在當我在將文件發送到服務器后添加命令mainpage()以返回到我的主頁面時,服務器陷入無限循環
ServerCode
if message[0] == "SAVE":
if not os.path.exists("C:\Heights\Documents\Projects\HomeWork\Project\Server1\\Files\\"+message[1].split("\\")[0]):
os.makedirs("C:\Heights\Documents\Projects\HomeWork\Project\Server1\\Files\\"+message[1].split("\\")[0])
file =open("C:\Heights\Documents\Projects\HomeWork\Project\Server1\\Files\\"+ message[1],"wb")
content = ""
while True:
data = current_socket.recv(1024)
if not data:
break
content += data
file.write(content)
file.close()
當我不嘗試返回時,文件到達服務器正常,但是當我添加一個額外的行時,服務器不會退出其接收所有文件內容的循環。 此外,如果我在完成寫入所有數據時嘗試從服務器獲得響應,則客戶端和服務器會卡住。
首先,作為一般規則,等待套接字返回任何內容(空字符串或其他內容)是一個壞主意。 這是因為在python中,如果另一方關閉了他的套接字,套接字只會返回空數據。 但是如果出現問題或者出於任何原因套接字沒有正確關閉,那么socket.recv方法可能無限地掛起。
其次,我發現你打算不止一次地實例化你的TKinter App。 這是不好的做法,你應該考慮隱藏你的主窗口。
希望我有所幫助。
Python的socket.recv(...)
繼承了Unix recv(2)
函數的語義,並且如recv(2)
man:
如果套接字上沒有可用消息,則接收呼叫等待消息到達,除非套接字是非阻塞的
因此,由於current_socket
是阻塞的,因此在將整個文件讀取到content
變量之后,您的服務器只會無限地掛起到data = current_socket.recv(1024)
行,直到客戶端上的套接字正確關閉為止。
為了避免這種情況
在發送任何內容之前, 在客戶端發送文件大小(以字節為單位):
import struct ... file_len_bytes = pack('!i', len(open_file)) s.send(file_len_bytes) while open_file: ....
在服務器端讀取您的文件大小,然后使用它來檢查是否已讀取整個文件:
import struct ... file_len_bytes = "" while len(file_len_bytes) < 4: file_len_bytes += client.recv(1) file_len = struct.unpack("!i", file_len_bytes[:4])[0] content = "" bytes_read = 0 while bytes_read < file_len: data = current_socket.recv(1024) bytes_read += len(data) content += data
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.