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

时间:2022-09-22 12:48:32

I'm pretty new at programming and esp network programming so if it's stupid, don't bash too hard please, thanks.

我在编程和esp网络编程方面是新手,所以如果它很笨,请不要太麻烦,谢谢。

I have client and server communicating with diagrams (UDP) in C. client sends 5 msgs and upon receiving msgs, server sends msgs back. receiving and sending messages are great until client has finished receiving the msgs. after server sending all msgs back, it terminates using close(). so recvfrom() from client should return 0, right?

我让客户端和服务器与c中的图(UDP)通信,客户端发送5个msgs,接收msgs后,服务器返回msgs。在客户端完成接收msgs之前,接收和发送消息是非常重要的。服务器将所有msgs发送回来后,使用close()终止。那么从客户端返回的recvfrom()应该返回0,对吧?

assuming recvfrom() should return 0 upon close() from server side, it returns -1 instead, with error Resource temporarily unavailable. is this resource reference to closed socket from server? or is it for something else entirely different like running out of buffer or something (which i don't think is true)?

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

and assuming my assumption was wrong and -1 is returned because server terminated, i probably should handle the error with

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

if(SOMEMACRO)
   do something 

but how do i find out what SOMEMACRO is? i print out the error but it says resource temp unavailable and recvfrom() description doesn't mention about unavilable resource..?

但是我怎么知道什么是SOMEMACRO呢?我打印出了错误,但是它说资源温度不可用,而recvfrom()描述中没有提到不可用资源。

btw this is a non blocking socket, if that makes any difference since i read that if O_NONBLOCK is set and no msgs are available, it would set errno to EAGAIN or EWOULDBLOCK. O_NONBLOCK isn't set but MSG_DONTWAIT is set. are they basically the same thing where O_NONBLOCK is for general file descriptors and MSG_DONTWAIT is socket specific??

顺便说一句,这是一个非阻塞套接字,如果这有什么区别,因为我读到如果O_NONBLOCK被设置并且没有msgs可用,那么它会将errno设置为EAGAIN或eif dblock。O_NONBLOCK没有设置,但MSG_DONTWAIT没有设置。它们基本上是相同的吗? O_NONBLOCK是通用文件描述符而MSG_DONTWAIT是特定于套接字的吗?

My brain isn't working all that great now, if someone could enlighten me and clarify what my confusion is about, i would deeply appreciate it. Thanks!

我的大脑现在运转得不太好,如果有人能启发我,澄清我的困惑,我会非常感激的。谢谢!

2 个解决方案

#1


13  

UDP is a stateless protocol, unlike TCP which is connection oriented. Your receiving code will not know whether or not the sender has closed its socket, it only knows whether or not there is data waiting to be read. According to the man page for recvfrom on Linux:

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

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and the external variable errno set to EAGAIN.

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

This seems to be what is happening for you

这似乎是发生在你身上的事情。

Edit: Note that "resource temporarily unavailable" and EAGAIN are the same error, one is just the user friendly descption vs the define name. Basically its just telling you that you are trying to read from the socket and there is no data to read

编辑:注意“资源暂时不可用”和EAGAIN是相同的错误,一个是用户友好的descption vs定义名称。基本上,它只是告诉您您正在尝试从套接字读取,并且没有数据要读取

#2


2  

After your have closed the socket it still lingers around for sometime. Usually about two minutes or so. To avoid this, use SO_REUSEADDR socket option.

你把插座关上后,它还会在附近徘徊一段时间。通常大约两分钟。要避免这种情况,请使用SO_REUSEADDR套接字选项。

Here are some references for you.

这里有一些你的参考资料。

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

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

And here is an example, scroll down to udp_listen function:

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

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

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

#1


13  

UDP is a stateless protocol, unlike TCP which is connection oriented. Your receiving code will not know whether or not the sender has closed its socket, it only knows whether or not there is data waiting to be read. According to the man page for recvfrom on Linux:

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

If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and the external variable errno set to EAGAIN.

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

This seems to be what is happening for you

这似乎是发生在你身上的事情。

Edit: Note that "resource temporarily unavailable" and EAGAIN are the same error, one is just the user friendly descption vs the define name. Basically its just telling you that you are trying to read from the socket and there is no data to read

编辑:注意“资源暂时不可用”和EAGAIN是相同的错误,一个是用户友好的descption vs定义名称。基本上,它只是告诉您您正在尝试从套接字读取,并且没有数据要读取

#2


2  

After your have closed the socket it still lingers around for sometime. Usually about two minutes or so. To avoid this, use SO_REUSEADDR socket option.

你把插座关上后,它还会在附近徘徊一段时间。通常大约两分钟。要避免这种情况,请使用SO_REUSEADDR套接字选项。

Here are some references for you.

这里有一些你的参考资料。

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

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

And here is an example, scroll down to udp_listen function:

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

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

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