簡體   English   中英

UDP非阻塞寫入失敗

[英]UDP non blocking write failure

我曾在非阻塞TCP中工作,因為在非阻塞情況下讀寫都可能失敗。 如果沒有可用數據,則TCP非阻塞讀取可能會失敗,如果對端的TCP緩沖區已滿(我希望TCP緩沖區大小為64K),則TCP寫入會失敗。

同樣,如果沒有可用數據,則UDP讀取( recvfrom )可能會失敗。 但是UDP寫入( sendto )失敗的情況是什么? 我認為在UDP寫中不會有任何非阻塞錯誤。 因為TCP寫入發送數據並等待來自另一端的ACK。 但這不是UDP寫入的情況,它只會發送並出來,它不會等待來自對等方的任何ACK。 如果它沒有發送到另一側,則意味着其數據包丟失。

我對UDP非阻塞寫入的理解是否正確? 請解釋 ?

UDP非阻塞發送失敗的最可能原因是UDP套接字的內核內傳出數據緩沖區已滿。 在這種情況下,send()/ sendto()將返回-1,而errno將被設置為EWOULDBLOCK。

請注意,非阻塞send()/ sendto()實際上不會在數據返回之前將其發送出網絡設備。 而是將數據復制到內核緩沖區中並立即返回,此后,內核負責將數據盡快移至網絡。 如果您的程序嘗試一次發送大量數據,則傳出數據緩沖區可能已滿,因為CPU可以將您的新數據添加到緩沖區中的速度比網絡硬件將緩沖區數據轉發到網絡中的速度要快得多。

如果收到-1 / EWOULDBLOCK錯誤,通常最優雅的處理方法是停止嘗試在該套接字上發送,直到套接字select()(或poll()等)准備就緒為止-寫。 發生這種情況時,您知道內核緩沖區至少已耗盡一部分,可以再次嘗試send()/ sendto()調用。

send()錯誤的另一個(不太可能)原因是,如果您嘗試發送到的IP地址無效。 無論如何,您都應該檢查errno並找出errno值是什么,因為這樣可以使您更好地了解問題所在。

順便說一下,上述行為也不是UDP獨有的。 如果您嘗試在套接字上發送()數據的速度快於本地網卡可能耗盡套接字的輸入,則非阻塞TCP套接字(即使遠程對等方的接收窗口未滿)也可能會遇到同樣的問題。內核緩沖區。

因為TCP寫入發送數據並等待來自另一端的ACK。

不,不是。 它將您的數據復制到套接字發送緩沖區,如果緩沖區已滿,它將阻塞或返回-1/EWOULDBLOCK/EAGAIN.

但這不是UDP寫入的情況,它只會發送並出來,它不會等待來自對等方的任何ACK。

不,不是。 它將您的數據復制到套接字發送緩沖區,如果緩沖區已滿,它將阻塞或返回-1/EWOULDBLOCK/EAGAIN.

在這兩種情況下,將字節實際寫入網絡都是與程序異步的。

暫無
暫無

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

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