简体   繁体   English

使用Python中的套接字将文件发送到服务器

[英]Sending a file to a server using sockets in Python

Mainpage displays my front page and upload is supposed to display the page where you enter the file you wish to store with the server 主页显示我的首页,上传应显示您输入要与服务器存储的文件的页面

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()

Now when I add the command mainpage() to return back to to my main page after sending the file to the server,the server gets stuck in an infinite loop 现在当我在将文件发送到服务器后添加命令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()

The file reaches the server fine when I don't try to return, but the moment I add that one extra line, the server doesn't exit its loop where it receives all the file content. 当我不尝试返回时,文件到达服务器正常,但是当我添加一个额外的行时,服务器不会退出其接收所有文件内容的循环。 Also,if I try to get a response from the server when it's done writing all the data down, the client and the server get stuck. 此外,如果我在完成写入所有数据时尝试从服务器获得响应,则客户端和服务器会卡住。

Firstly, As a general rule, waiting for the socket to return nothing(empty string or whatever), is a bad idea. 首先,作为一般规则,等待套接字返回任何内容(空字符串或其他内容)是一个坏主意。 That is because in python a socket would only return empty data if the other side closed his socket. 这是因为在python中,如果另一方关闭了他的套接字,套接字只会返回空数据。 But if there was a problem or for any reason the socket was not closed properly, the socket.recv method would hang perhaps infinitely. 但是如果出现问题或者出于任何原因套接字没有正确关闭,那么socket.recv方法可能无限地挂起。

Secondly, I see that you intend to instantiate your TKinter App more than once. 其次,我发现你打算不止一次地实例化你的TKinter App。 This is bad practice, and you should consider just hiding your main window. 这是不好的做法,你应该考虑隐藏你的主窗口。

Hope I was helpful. 希望我有所帮助。

Python's socket.recv(...) inherits semantics from Unix recv(2) function, and as stated in recv(2) man: Python的socket.recv(...)继承了Unix recv(2)函数的语义,并且如recv(2) man:

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking 如果套接字上没有可用消息,则接收呼叫等待消息到达,除非套接字是非阻塞的

Therefore, since current_socket is blocking, your server just hangs on the line data = current_socket.recv(1024) infinitely right after the whole file has been read to the content variable until the socket on the client becomes properly closed. 因此,由于current_socket是阻塞的,因此在将整个文件读取到content变量之后,您的服务器只会无​​限地挂起到data = current_socket.recv(1024)行,直到客户端上的套接字正确关闭为止。

To avoid that: 为了避免这种情况

  • On the client side send your file size in bytes before sending any of its contents: 发送任何内容之前, 在客户端发送文件大小(以字节为单位):

     import struct ... file_len_bytes = pack('!i', len(open_file)) s.send(file_len_bytes) while open_file: .... 
  • On the server side read your file size and then use it to check whether the whole file has been read: 在服务器端读取您的文件大小,然后使用它来检查是否已读取整个文件:

     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