為什么這些Python發(fā)送/接收套接字函數(shù)在緩慢調(diào)用時(shí)可以工作,但在連續(xù)快速調(diào)用時(shí)會(huì)失?。?/h1>
2 回答

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個(gè)贊
看起來您正在重復(fù)使用相同的連接,而發(fā)生的情況是您的file_socket
緩沖意味著...您實(shí)際上已經(jīng)recv
從套接字中讀取了更多內(nèi)容,然后您會(huì)通過讀取循環(huán)來思考。
即接收器從您的套接字消耗更多數(shù)據(jù),并且下次您嘗試readline()
最終讀取前一個(gè)文件的其余部分,直到其中包含的新行或下一個(gè)長度信息。
這也意味著您最初的問題實(shí)際上是您跳過了一段時(shí)間。下一個(gè)讀取行的效果不是int
您預(yù)期的,因此觀察到了失敗。
你可以說:
with sock.makefile('rb', buffering=0) as file_socket:
相反,強(qiáng)制文件訪問不被緩沖?;蛘邔?shí)際自行處理傳入字節(jié)的接收、緩沖和解析(了解一個(gè)文件的結(jié)束位置和下一個(gè)文件的開始位置)(而不是像包裝器和 那樣的文件)readline
。

TA貢獻(xiàn)2041條經(jīng)驗(yàn) 獲得超4個(gè)贊
您必須了解套接字通信是基于 TCP/IP 的,無論是同一臺(tái)機(jī)器(在這種情況下使用環(huán)回)還是不同的機(jī)器都無關(guān)緊要。因此,您已經(jīng)獲得了一些在其之間建立連接的 IP 地址。更進(jìn)一步,它涉及訪問您的網(wǎng)絡(luò)適配器,即與訪問例如網(wǎng)絡(luò)適配器相比需要相對較長的時(shí)間。內(nèi)存。此外,適配器本身管理何時(shí)發(fā)送特定數(shù)據(jù)幀(較低的 ISO/OSI 層)?;旧?,對于 TCP,需要 ACK,但在標(biāo)準(zhǔn) PC 上,這通常不是某些工業(yè)實(shí)時(shí)以太網(wǎng)。
因此,在您的代碼中,您有一個(gè)while True
沒有任何睡眠的循環(huán),并且您不檢查sock.send
返回的內(nèi)容。即使特定數(shù)據(jù)幀出現(xiàn)問題,您也會(huì)忽略它并嘗試發(fā)送下一個(gè)。乍一看,似乎有些內(nèi)容已被緩存,并且接收者收到了重新建立連接后刷新的內(nèi)容。
因此,您應(yīng)該做的第一件事是檢查是否sock.send
確實(shí)返回了發(fā)送的字節(jié)數(shù)。如果沒有,我相信應(yīng)該重新發(fā)送該幀。在這種情況下,我強(qiáng)烈建議的另一件事是考慮一些自定義協(xié)議(這通常在 OSI/ISO 堆棧的上下文中稱為應(yīng)用程序?qū)?/strong>)。例如,您可能有 4 種類型的幀:START、FILESIZE、DATA、END,分配唯一 ID 并以標(biāo)識(shí)符開始每個(gè)幀。然后,START 將是空的,F(xiàn)ILESIZE 將包含單個(gè) uint16,DATA 將包含 {FILE NUMBER, LINE NUMBER, LINE_LENGTH, LINE},END 將是空的。然后,一旦您在客戶端上獲得了整個(gè)框架,您就可以安全地組合收到的信息。
添加回答
舉報(bào)