2012-12-12 56 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()调用返回后马上检查返回值。