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

时间:2017-06-07 18:39:46

标签: python sockets

主页显示我的首页,上传应该显示页面 您输入要与服务器一起存储的文件的位置

SELECT MemberID, MemberName, MemberAge,FROM Members 
(SELECT AVG(Members.MemberAge) AS AverageAge)
WHERE MemberAge>=AverageAge

现在,当我将文件发送到服务器后添加命令mainpage()返回到我的主页面时,服务器陷入无限循环

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

当我不尝试返回时,文件到达服务器正常,但是当我添加一个额外的行时,服务器不会退出其接收所有文件内容的循环。此外,如果我在完成写入所有数据时尝试从服务器获得响应,则客户端和服务器会卡住。

2 个答案:

答案 0 :(得分:0)

首先,作为一般规则,等待套接字不返回任何内容(空字符串或其他内容),这是一个坏主意。那是因为在python中一个套接字只会在另一边关闭他的套接字时返回空数据。但是如果出现问题或者出于任何原因套接字没有正确关闭,那么socket.recv方法会或许无限地挂起。

其次,我发现你打算不止一次地实例化你的TKinter App。 这是不好的做法,你应该考虑隐藏你的主窗口。

希望我能提供帮助。

答案 1 :(得分:0)

Python socket.recv(...)继承了Unix recv(2)函数的语义,并且如recv(2) man所述:

  

如果套接字上没有可用的消息,则接收呼叫等待消息到达,除非套接字是非阻塞的

因此,由于current_socket正在阻塞,因此在将整个文件读取到data = current_socket.recv(1024)变量之后,服务器只会无​​限地挂在行content上,直到客户端上的套接字变为正确关闭。

为避免这种情况:

  • 在客户端在发送任何内容之前以字节为单位发送文件大小:

    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