[Mono-bugs] [Bug 62398][Nor] New - Non-blocking connect broken under Linux
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Wed, 4 Aug 2004 00:56:50 -0400 (EDT)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by michi@zeroc.com.
http://bugzilla.ximian.com/show_bug.cgi?id=62398
--- shadow/62398 2004-08-04 00:56:50.000000000 -0400
+++ shadow/62398.tmp.18891 2004-08-04 00:56:50.000000000 -0400
@@ -0,0 +1,153 @@
+Bug#: 62398
+Product: Mono: Class Libraries
+Version: unspecified
+OS:
+OS Details: RedHat 8, dual-CPU machine
+Status: NEW
+Resolution:
+Severity:
+Priority: Normal
+Component: System
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: michi@zeroc.com
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: Non-blocking connect broken under Linux
+
+I'm doing a non-blocking connect on a TCP socket. The server accepts the
+connection, and the client gets a writeable file descriptor from Select()
+after calling Connect(). Once Select() reports the connection as
+established, the socket is *not* connected. (The Connected property is
+false and any attempt at reading from the socket throws a "not connected"
+exception.)
+
+Very simple server and client code appear below. Note that the identical
+code works fine under Windows with both the Mono and the .NET run time, so
+this appears to be a bug in the Linux socket library implementation.
+
+Note the output of the client:
+
+ Got connect in progress, as expected.
+ Connection is ready.
+ What!? Socket is ready for writing but not connected?!
+ Hmmm... Let's try again...
+ Connection is ready.
+ Socket is connected.
+
+Under Windows, the same program prints:
+
+ Got connect in progress, as expected.
+ Connection is ready.
+ Socket is connected.
+
+I think it's simply illegal for Select() to return a writable descriptor
+after the non-blocking connect, but for the connection not to be
+established at this point. Incidentally, calling select repeatedly after
+the non-blocking connect doesn't help -- the socket keeps getting reported
+as writeable, but stays unconnected. Calling getsockopt() after the select
+to check for the error status returns no error.
+
+
+Cheers,
+
+Michi.
+
+
+
+Server code:
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+public class Server
+{
+ public static void Main(string[] args)
+ {
+ Socket listenSocket = new Socket(AddressFamily.InterNetwork,
+SocketType.Stream, ProtocolType.Tcp);
+
+ IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
+ IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 10000);
+ listenSocket.Bind(ipEndpoint);
+ listenSocket.Listen(1);
+ Socket connection = listenSocket.Accept();
+ Thread.Sleep(10000);
+ }
+}
+
+
+Client code:
+
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Net;
+using System.Net.Sockets;
+
+public class Client
+{
+ public static void Main(string[] args)
+ {
+ Socket socket = new Socket(AddressFamily.InterNetwork,
+SocketType.Stream, ProtocolType.Tcp);
+
+ IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
+ IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 10000);
+
+ socket.Blocking = false; // We want a non-blocking
+connect
+
+ repeatConnect:
+ try
+ {
+ socket.Connect(ipEndpoint);
+ }
+ catch(Win32Exception ex)
+ {
+ int code = ex.NativeErrorCode;
+ if ( code != 10035 // WSAEWOULDBLOCK
+ && code != 10036) // WSAEINPROGRESS
+ {
+ Console.Error.WriteLine("Connect failed.");
+ Environment.Exit(1);
+ }
+ System.Console.WriteLine("Got connect in progress, as expected.");
+ }
+
+ bool ready;
+ bool error;
+ ArrayList writeList = new ArrayList();
+ writeList.Add(socket);
+ ArrayList errorList = new ArrayList();
+ errorList.Add(socket);
+ Socket.Select(null, writeList, errorList, 10000000); // 10 second
+timeout
+ ready = writeList.Count != 0;
+ error = errorList.Count != 0;
+ Debug.Assert(!(ready && error));
+
+ if (ready)
+ {
+ Console.WriteLine("Connection is ready.");
+ if (!socket.Connected)
+ {
+ Console.Error.WriteLine("What!? Socket is ready for writing
+but not connected?!");
+ Console.Error.WriteLine("Hmmm... Let's try again...");
+ goto repeatConnect; // Rather
+ugly work-around for this bug.
+ }
+ else
+ {
+ Console.WriteLine("Socket is connected.");
+ }
+ }
+
+ Environment.Exit(0);
+ }
+}