2012-12-12 50 views
5

我提出一個無阻塞的一個插座,旁邊一個阻塞發送呼叫收到另一個插座。之後,我想檢查非阻塞發送是成功還是失敗。如何才能做到這一點?檢查非阻塞發送成功

while (i) 
    { 
     retval = send (out_sd, s_message, strlen (s_message), MSG_DONTWAIT); 
     retval = recv (client_sd, r_message, MSG_LEN, 0); 
     r_message[retval] = '\0'; 
     /* Here I want to wait for the non-blocking send to complete */ 
     strcpy (s_message, r_message); 
     strcpy (r_message, ""); 
     i--; 
    } 
+0

是否可以使用回撥? – andre

+1

我不這麼認爲。只需在進入下一次迭代之前檢查發送的消息是失敗還是成功或排隊。 – phoxis

+0

使用兩個不同的var/s來存儲send/recv的結果。 – alk

回答

5

你以某種方式混合同步和異步IO,這通常是一個有點混亂,但我看不出這裏有什麼實際問題。

避免硬輪詢(這是保持看,如果你的操作在一個循環中完成),你應該使用select()等待您的頻道/插座變得可用更多的寫操作。這會告訴你前一個已經完成(或者它完全由你的操作系統負責,這是相同的)。

的select()函數是C語言爲異步IO的基礎,你應該在here讀到它,並且this是一個例子,我認爲可能對你有用。

注重儘管這select()的支持讀,寫和異常事件的例子顯示了一個讀取選擇,你想要做一個寫選擇。

+0

是的,我有混合的同步和異步I/O,但在不同的套接字中,我認爲這將工作正常。每個進程都會執行這一段代碼,因此如果兩者都被阻塞,那麼就會出現死鎖。因此,我首先發送消息,然後等待接收。在一個進程接收到數據後,它應該在進入下一次迭代之前檢查最後一次非阻塞發送是否成功。 – phoxis

+1

我不知道詳細信息,但是如果兩個套接字都連接相同的兩個程序,您確定不能只使用同步調用嗎?就像程序A執行READ - > WRITE - > READ - >等一樣,程序B執行WRITE - > READ - > WRITE - >等。這就是通常所做的事情,並且沒有死鎖。 –

+0

是的,這是一種替代讀寫的可能性,但我想避免這方面。 – phoxis

1

send()將返回發送的字節數或發生錯誤時的-1

如果網絡堆棧中有足夠的緩衝區來發送消息中的至少一些字節,則retval將包含發送的字節數,該字節數可能小於要發送的字節數。如果網絡堆棧緩衝區已滿,它將包含-1errno將被設置爲EAGAINEWOULDBLOCK

在所有情況下,發送調用,只要它返回的是完整的。所以你不必等待非阻塞發送在其他地方完成,你需要在send()調用返回後馬上檢查返回值。