2016-07-20 104 views
-1

在我目前正在處理的應用程序中,如果我意識到這不是我要找的,我需要停止下載某個文件。在我開始接收文件之前,協議沒有提供任何方式來知道它(如標題或其他)。中斷通過套接字下載(recv)文件通過套接字

作爲一個例子,在某些情況下,我可能正在尋找一個大小正確爲X字節的文件,但是在我下載了X字節並繼續獲取更多字節後,這不是我正在尋找的文件其大小大於X.在這種情況下,我想停止下載以釋放網絡帶寬資源。該協議不提供任何方式通知服務器這一點。

我在某處讀取close(fd)shutdown(fd, SHUT_RD)將不會實際停止下載,因爲服務器將繼續send()該文件,這將繼續消耗網絡帶寬。我也不確定如果我停止呼叫recv()並且數據包仍然到達,它們是否會填充緩衝區,然後開始丟棄?如果它很重要,則使用的協議基於TCP(但我希望某些解決方案也可用於基於UDP的協議)。

我就更加懷疑停止呼叫recv()會解決這個問題,我搜索了編程帶寬控制(sleep(),令牌桶..)作爲一種替代解決方案(降低下載速度接近零的我知道後後它不是我正在尋找的文件)。如果服務器仍然是send() ing,如何通過減少recv()調用來控制網絡帶寬使用情況?我沒有抓住它。

主要想法是完全停止下載。

你會建議什麼?

+2

TCP是基於連接的協議,所以基本上如果關閉連接,服務器將最終停止發送。 –

+2

是什麼讓你認爲服務器會繼續發送數據包?在最壞的情況下,當你關閉客戶端套接字時,你的服務器在發送時會出現套接字錯誤,並停止發送數據。您對此類基本要求的細節過於擔心。 – x82

+0

此外,請不要考慮使用UDP發送文件。 UDP是不可靠的,這意味着您甚至不會收到有關到達目的地的數據包的響應。這不是一個選項。 – x82

回答

1

我讀的地方,close(fd)shutdown(fd, SHUT_RD)不會真正停止下載,服務器將繼續send()文件,這將繼續消耗網絡帶寬。

如果shutdown(fd, SHUT_RD)自己recv()將與零返回代碼,這會導致代碼以關閉插座,這將導致如果有更多的數據來自於同行,本地主機發出一個RST解除其將在發件人處引發一個ECONNRESET(在幾個send()調用之後,不一定立即)。

你從哪裏讀到這個廢話?

我就更加懷疑,如果停止調用recv()會解決它

它不會解決它,但它最終會從發送停止發送,因爲TCP流量控制。這不是解決這個問題的方法。

+0

很好。我不太瞭解TCP。謝謝。關於這個廢話:也許是關於UDP,我沒有注意到...... –

+0

關於TCP流量控制:這意味着如果我減慢傳輸速度(通過減少'recv()'調用'sleep()')很多,是否有連接關閉的風險?或者這隻適用於完全停止調用'recv()'? –

+1

如果您收到的郵件發送速度比發件人慢,發件人最終會被阻止,如果他處於阻止模式,或者EAGAIN/EWOULDBLOCK(如果他處於非阻止模式)。這包括根本沒有收到的情況。 – EJP