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

标签 python sockets

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

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(...)继承自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



因此,由于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
    
  • 关于python - 使用Python中的套接字将文件发送到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44420420/

    相关文章:

    python - 从 ESP32 读取数据到 Python 时出现问题

    python - Tkinter 对曲线使用什么插值?

    linux - 在 Linux 上关闭已建立的 TCP 连接

    javascript - 在 python django 中通过 url 发送数组

    python - Pandas 读取嵌套的 json

    c - 如何用socket地址获取自己的IP地址?

    java - ServerSocket.accept() 抛出 SocketTimeoutException 并显示 null 消息

    c++ - 即使文件描述符不可用,也能有效地监听多个套接字

    java - 从其他线程更新 Swing GUI

    python - 在字符串中的多个位置替换变量