X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Date: Thu, 25 Oct 2007 11:58:35 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: strange select() and recvfrom() behaviour Message-ID: <20071025095835.GP20400@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <43152 DOT 131 DOT 220 DOT 7 DOT 1 DOT 1193247097 DOT squirrel AT webmail DOT iai DOT uni-bonn DOT de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <43152.131.220.7.1.1193247097.squirrel@webmail.iai.uni-bonn.de> User-Agent: Mutt/1.5.16 (2007-06-09) Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 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/