This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: strange select() and recvfrom() behaviour


On Oct 24 19:31, Marcell Missura wrote:
> Hi,
> 
> actually you were right, I was a bit too quick with my extract. It didn't
> contain an important line. I'm also sending out stuff through that socket.
> So here it goes, you can copy paste and compile this.

Maybe you were also a little quick with your code.  You don't really
test what's going on, so your code is going crazy.

What happens is that you call send() all the time if there's nothing to
read.  When nothing has been read so far, you call send() with a random
value for the peer address, which results in some arbitrary errno (which
you never test), in my case EAFNOSUPPORT.

After you called recvfrom() for the first time, you call send()
subsequently with the last peer address you got from recvfrom().  This
works fine as long as the peer doesn't close the connection.  After the
peer closed the connection, send() returns with 0 (EOF, which you never
test).  However, the next select *has* something on the socket, which is
an error message.  recvfrom() returns with -1 and errno (which you never
test) set to ECONNRESET.

The next time select is called, it does *not* return with -1, but with
0, a simple timeout.  So send() is called with the same old peer address
again.  It returns 0 (EOF, which you never test), thus resulting in
select again having something to say on the socket.  Again you get an
errno of ECONNRESET (which you never test) from recvfrom(), and the game
goes on ad infinitum.

The fact that select() returns with a readable socket and the recvfrom
function returning ECONNRESET is covered by SUSv3(*), even though this
does not happen on Linux:

 "[ECONNRESET]   A connection was forcibly closed by a peer."

MSDN(**) has the following to say in the ECONNRESET case:

 "WSAECONNRESET

  The virtual circuit was reset by the remote side executing a hard or
  abortive close. The application should close the socket; it is no
  longer usable. On a UDP-datagram socket this error indicates a
  previous send operation resulted in an ICMP Port Unreachable message."

There is a way to disable this behaviour(***), at least on W2K, but
the better approach would be to fix your code, IMHO.


Corinna


(*) http://www.opengroup.org/onlinepubs/009695399/functions/recvfrom.html
(**) http://msdn2.microsoft.com/en-us/library/ms740120.aspx
(***) http://support.microsoft.com/kb/263823


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]