UDP和套接字,recvfrom()返回-1,资源暂时不可用

时间:2010-03-04 13:08:09

标签: c sockets client udp

我有一个客户端和服务器在C中与数据报(UDP)通信。客户端发送5个消息,并在收到消息后,服务器发回消息。在客户端完成接收消息之前,接收和发送消息是很好的。服务器发回所有消息后,它将使用close()终止。所以来自客户端的recvfrom()应该返回0,对吗?

假设recvfrom()在服务器端close()时返回0,则返回-1,错误资源暂时不可用。此资源是否是从服务器关闭套接字的引用?或者它是否用于其他完全不同的东西,如用完缓冲区或其他东西(我认为不是这样)?

假设我的假设是错误的并且由于服务器终止而返回-1,我可能应该用

处理错误
if(SOMEMACRO)
   do something 

如何找出SOMEMACRO是什么?我打印出错误,但它说资源临时不可用,recvfrom()描述没有提到无法使用的资源..?

顺便说一句,这是一个非阻塞套接字,如果这有任何区别,因为我读到如果设置了O_NONBLOCK并且没有可用的消息,它会将errno设置为EAGAIN或EWOULDBLOCK。未设置O_NONBLOCK但设置了MSG_DONTWAIT。它们与一般文件描述符的O_NONBLOCK基本相同,而MSG_DONTWAIT是特定于套接字的吗?

我的大脑现在没有那么好的工作,如果有人可以启发我并澄清我的困惑,我会深深体会到这一点。谢谢!

2 个答案:

答案 0 :(得分:14)

UDP是一种无状态协议,与面向连接的TCP不同。您的接收代码将不知道发件人是否已关闭其套接字,它只知道是否有数据等待读取。根据Linux上recvfrom的手册页:

  

如果套接字上没有可用的消息,则接收调用等待消息到达,除非套接字是非阻塞的(请参阅fcntl(2)),在这种情况下返回值-1并将外部变量errno设置为EAGAIN。

这似乎是你发生的事情

编辑:请注意,“资源暂时不可用”和EAGAIN是相同的错误,一个是用户友好的描述与定义名称。基本上它只是告诉你,你正试图从套接字读取,没有数据可供阅读

答案 1 :(得分:2)

关闭套接字后,它仍然会在一段时间内徘徊。通常大约两分钟左右。要避免这种情况,请使用SO_REUSEADDR套接字选项。

以下是一些参考资料。

http://msdn.microsoft.com/en-us/library/ms740476%28VS.85%29.aspx http://docs.hp.com/en/B2355-90136/ch03s01.html

这是一个例子,向下滚动到udp_listen函数:

http://www.codase.com/search/display?file=L2dlbnRvbzIvdmFyL3RtcC9yZXBvcy9jb2Rhc2UuYy9zbGlycC0xLjAuMTYvd29yay9zbGlycC0xLjAuMTYvc3JjL3VkcC5j&lang=c&off=15730+15796+