簡體   English   中英

使用Python中的套接字將文件發送到服務器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM