簡體   English   中英

Python套接字,從服務器請求文件,然后等待接收它

[英]Python Sockets, requesting file from server then waiting to receive it

我試圖使用特定的文件名從客戶端向我的服務器發送一個字符串,然后將該文件發送給客戶端。 由於某種原因,即使在收到所有文件后它也會掛起。 它掛在:

m = s.recv(1024)

client.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.2", 54321))
s.send(b"File:test.txt")
f = open("newfile.txt", "wb")
data = None
while True:
    m = s.recv(1024)
    data = m
    if m:
        while m:
            m = s.recv(1024)
            data += m
        else:
            break
f.write(data)
f.close()
print("Done receiving")

server.py

import socket
import os

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 54321))

while True:
    client_input = c.recv(1024)
    command = client_input.split(":")[0]
    if command == "File":
        command_parameter = client_input.split(":")[1]
        f = open(command_parameter, "rb")
        l = os.path.getsize(command_parameter)
        m = f.read(l)
        c.sendall(m)
        f.close()

TLDR

recv阻止的原因是因為發送文件數據后套接字連接沒有關閉。 當前,實現無法知道通信何時結束,這將導致兩個遠程進程之間出現死鎖。 為避免這種情況,請關閉服務器中的套接字連接,這將在客戶端中生成文件結束事件(即recv返回長度為零的字符串)。

更多見解

每當設計任何軟件時,兩個進程相互通信,就必須定義一個消除通信歧義的協議 ,以便兩個對等方始終清楚地知道它們處於哪種狀態。 通常,這涉及使用通信的語法來幫助指導數據的解釋。

當前,您的實現存在一些問題:它沒有定義解決潛在歧義的適當協議。 當您考慮到一個對等方send每個調用不一定完全對應於另一方對recv調用時,這一點變得顯而易見。 也就是說, sendrecv的調用不一定是一對一的。 考慮將文件名發送到嚴重擁塞的網絡上的服務器:在第一次調用recv返回時,可能只有一半的文件名將其發送到服務器。 服務器無法(當前)知道它是否已完成接收文件名。 客戶端中也是如此:客戶端如何知道文件何時完成?

要解決此問題,我們可以在協議中引入一些語法,在服務器中引入一些邏輯,以確保在繼續操作之前獲得完整的文件名。 一個簡單的解決方案是使用EOL字符,即\\n表示客戶端消息的結尾。 現在,在您的測試中99.99%的時間將需要一次調用recv來讀入。但是,您必須預料到可能需要多次調用recv 顯然,這可以使用循環來實現。

對於此演示,客戶端更為簡單。 如果在發送文件之后通信結束,則可以使用該事件來表示數據流的結尾。 當服務器在其末端關閉連接時,會發生這種情況。

如果我們要將實現擴展到允許多個背對背文件的請求,那么我們就必須在協議中引入某種機制來區分一個文件的結尾和另一個文件的開頭。 請注意,這還意味着服務器可能需要緩沖它在以前的迭代中讀取的額外字節,以防出現重疊。 通常,流實現對於這類事情很有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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