亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么這些Python發送/接收套接字函數在緩慢調用時可以工作,但在連續快速調用時會失敗?

為什么這些Python發送/接收套接字函數在緩慢調用時可以工作,但在連續快速調用時會失???

九州編程 2023-06-27 17:22:24
我有一個客戶端和一個服務器,服務器需要向客戶端發送許多文本文件。發送文件函數接收套接字和要發送的文件的路徑:CHUNKSIZE = 1_000_000def send_file(sock, filepath):    with open(filepath, 'rb') as f:        sock.sendall(f'{os.path.getsize(filepath)}'.encode() + b'\r\n')        # Send the file in chunks so large files can be handled.        while True:            data = f.read(CHUNKSIZE)            if not data:                break            sock.send(data)接收文件函數接收客戶端套接字和保存傳入文件的路徑:CHUNKSIZE = 1_000_000def receive_file(sock, filepath):    with sock.makefile('rb') as file_socket:        length = int(file_socket.readline())        # Read the data in chunks so it can handle large files.        with open(filepath, 'wb') as f:            while length:                chunk = min(length, CHUNKSIZE)                data = file_socket.read(chunk)                if not data:                    break                f.write(data)                length -= len(data)    if length != 0:        print('Invalid download.')    else:        print('Done.')它的工作原理是將文件大小作為第一行發送,然后逐行發送文本文件。兩者都是在客戶端和服務端循環調用,從而將文件一一發送并保存。如果我設置斷點并緩慢調用這些函數,效果會很好。但是如果我讓程序不間斷地運行,它在讀取第二個文件的大小時會失?。?nbsp; File "/home/stark/Work/test/networking.py", line 29, in receive_file    length = int(file_socket.readline())ValueError: invalid literal for int() with base 10: b'00,1851,-34,-58,782,-11.91,13.87,-99.55,1730,-16,-32,545,-12.12,19.70,-99.55,1564,-8,-10,177,-12.53,24.90,-99.55,1564,-8,-5,88,-12.53,25.99,-99.55,1564,-8,-3,43,-12.53,26.54,-99.55,0,60,0\r\n'顯然,該線路正在接收更多的數據length = int(file_socket.readline())。我的問題:這是為什么?鑒于該行始終以尾隨發送,難道該行不應該只讀取大小嗎\n?如何解決此問題以便可以連續發送多個文件?
查看完整描述

2 回答

?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

看起來您正在重復使用相同的連接,而發生的情況是您的file_socket緩沖意味著...您實際上已經recv從套接字中讀取了更多內容,然后您會通過讀取循環來思考。

即接收器從您的套接字消耗更多數據,并且下次您嘗試readline()最終讀取前一個文件的其余部分,直到其中包含的新行或下一個長度信息。

這也意味著您最初的問題實際上是您跳過了一段時間。下一個讀取行的效果不是int您預期的,因此觀察到了失敗。

你可以說:

with sock.makefile('rb', buffering=0) as file_socket:

相反,強制文件訪問不被緩沖?;蛘邔嶋H自行處理傳入字節的接收、緩沖和解析(了解一個文件的結束位置和下一個文件的開始位置)(而不是像包裝器和 那樣的文件)readline。


查看完整回答
反對 回復 2023-06-27
?
縹緲止盈

TA貢獻2041條經驗 獲得超4個贊

您必須了解套接字通信是基于 TCP/IP 的,無論是同一臺機器(在這種情況下使用環回)還是不同的機器都無關緊要。因此,您已經獲得了一些在其之間建立連接的 IP 地址。更進一步,它涉及訪問您的網絡適配器,即與訪問例如網絡適配器相比需要相對較長的時間。內存。此外,適配器本身管理何時發送特定數據幀(較低的 ISO/OSI 層)。基本上,對于 TCP,需要 ACK,但在標準 PC 上,這通常不是某些工業實時以太網。

因此,在您的代碼中,您有一個while True沒有任何睡眠的循環,并且您不檢查sock.send返回的內容。即使特定數據幀出現問題,您也會忽略它并嘗試發送下一個。乍一看,似乎有些內容已被緩存,并且接收者收到了重新建立連接后刷新的內容。

因此,您應該做的第一件事是檢查是否sock.send確實返回了發送的字節數。如果沒有,我相信應該重新發送該幀。在這種情況下,我強烈建議的另一件事是考慮一些自定義協議(這通常在 OSI/ISO 堆棧的上下文中稱為應用程序層)。例如,您可能有 4 種類型的幀:START、FILESIZE、DATA、END,分配唯一 ID 并以標識符開始每個幀。然后,START 將是空的,FILESIZE 將包含單個 uint16,DATA 將包含 {FILE NUMBER, LINE NUMBER, LINE_LENGTH, LINE},END 將是空的。然后,一旦您在客戶端上獲得了整個框架,您就可以安全地組合收到的信息。


查看完整回答
反對 回復 2023-06-27
  • 2 回答
  • 0 關注
  • 171 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號