[Mono-bugs] [Bug 75558][Maj] New - asynchronous TCP connects in OS X do not work

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Fri Jul 15 16:24:33 EDT 2005


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 allan at imeem.com.

http://bugzilla.ximian.com/show_bug.cgi?id=75558

--- shadow/75558	2005-07-15 16:24:33.000000000 -0400
+++ shadow/75558.tmp.1529	2005-07-15 16:24:33.000000000 -0400
@@ -0,0 +1,200 @@
+Bug#: 75558
+Product: Mono: Class Libraries
+Version: 1.1
+OS: 
+OS Details: OS X 10.4.2
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Major
+Component: CORLIB
+AssignedTo: mono-bugs at ximian.com                            
+ReportedBy: allan at imeem.com               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: asynchronous TCP connects in OS X do not work
+
+Please fill in this template when reporting a bug, unless you know what you are doing.
+Description of Problem:
+
+Asynchronous TCP connections in OS X do not work. Some async operations like reads and writes 
+(and maybe asynchronous accepting of connections),  do work, but asynchronous connections 
+using BeginConnect do not. This is probably the same bug as #75436, but that bug report does 
+not contain code to reproduce. This may be related to a buggy Monitor implementation on OS X.
+
+Steps to reproduce the problem:
+
+The following program will work under mono 1.1.8.1 on Linux, but not on OS X:
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace AsyncConnectTest
+{
+	/// <summary>
+	/// Summary description for Class1.
+	/// </summary>
+	class Class1
+	{
+
+		private static Socket listenSock;
+		private static object procedureLock = new Object();
+
+		/// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		[STAThread]
+		static void Main(string[] args)
+		{
+			Thread th = new Thread(new ThreadStart(ServerHandler));
+			th.Start();
+			
+			// now wait for the socket to open
+			lock(procedureLock) 
+			{
+				Monitor.Wait(procedureLock);
+			}
+			IPEndPoint iep = new IPEndPoint( IPAddress.Loopback, ((IPEndPoint)
+listenSock.LocalEndPoint).Port);
+			Console.WriteLine("Trying to connect to "  + iep.Address + ":" + iep.Port);
+			Socket outgoing = new Socket(AddressFamily.InterNetwork,SocketType.Stream, 
+ProtocolType.Tcp);
+			
+			try 
+			{
+				outgoing.BeginConnect(iep,new AsyncCallback
+(ConnectionCallback),outgoing);
+			} 
+			catch(Exception e) 
+			{
+				Console.WriteLine("Got Exception while calling BeginConnect");
+			}
+			lock(procedureLock) 
+			{
+				if(!Monitor.Wait(procedureLock,5000)) 
+				{
+					Console.WriteLine("connection attempt timed out - WTF??? Async 
+Connect is BROKEN!");
+					try 
+					{
+						Console.WriteLine("And to prove it - here we try a regular connect 
+attempt");
+						Socket outgoing2 = new Socket
+(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
+						outgoing2.Connect(iep);
+						if(outgoing2.Connected) 
+						{
+							Console.WriteLine("However - we Connected successfully 
+using ye-olde fashioned method");
+						}
+						outgoing2.Close();
+					} 
+					catch(Exception e) 
+					{
+						Console.WriteLine("Can't connect using Synchronous method - 
+check your network setup");
+					}
+					listenSock.Close();
+					outgoing.Close();
+				}
+			}
+		}
+
+
+		static void ConnectionCallback(IAsyncResult iar) 
+		{
+			Socket sock = (Socket) iar.AsyncState;
+			try 
+			{
+				sock.EndConnect(iar);
+				if(sock.Connected) 
+				{
+					IPEndPoint iep =(IPEndPoint) sock.RemoteEndPoint;
+					Console.WriteLine("Successfully Connected to server");
+					lock(procedureLock) 
+					{
+						Monitor.Pulse(procedureLock);
+					}
+				} 
+				else 
+				{
+					Console.WriteLine("WTF? EndConnect completed but we're not 
+connected?");
+				}
+			} 
+			catch (Exception e) 
+			{
+				Console.WriteLine("Exception while calling EndConnect " + e);
+			}
+			sock.Close();
+		}
+
+		static void ServerHandler() 
+		{
+			try 
+			{
+				listenSock = new Socket(AddressFamily.InterNetwork,SocketType.Stream, 
+ProtocolType.Tcp);
+				IPEndPoint iep = new IPEndPoint(IPAddress.Any,0);
+				listenSock.Bind(iep);
+				listenSock.Listen(10);
+				iep = (IPEndPoint) listenSock.LocalEndPoint;
+				Console.WriteLine("created Listening socket on port " + iep.Port);
+				lock(procedureLock) 
+				{
+					Monitor.Pulse(procedureLock);
+				}
+			
+				Socket incoming = listenSock.Accept();
+				iep = (IPEndPoint) incoming.RemoteEndPoint;
+				Console.WriteLine("Accepted new socket from " + iep.Address + ":" + 
+iep.Port);
+				Thread.Sleep(1000);
+				incoming.Close();
+				listenSock.Close();
+				// end of program
+			} 
+			catch (Exception e) 
+			{
+				Console.WriteLine("got exception on listening socket " + e);
+			}
+		}
+	}
+}
+
+Actual Results:
+
+Under OS X 10.4.2:
+
+created Listening socket on port 52168
+Trying to connect to 127.0.0.1:52168
+connection attempt timed out - WTF??? Async Connect is BROKEN!
+And to prove it - here we try a regular connect attempt
+However - we Connected successfully using ye-olde fashioned method
+got exception on listening socket System.Net.Sockets.SocketException: Network subsystem is 
+down
+in <0x00230> System.Net.Sockets.Socket:Accept ()
+in <0x001b0> AsyncConnectTest.Class1:ServerHandler ()
+
+Expected Results:
+
+Under Linux:
+
+created Listening socket on port 32938
+Trying to connect to 127.0.0.1:32938
+Successfully Connected to server
+Accepted new socket from 127.0.0.1:32939
+
+How often does this happen? 
+Every time.
+
+Additional Information:
+This may have something to do with the OS X Monitor implementation; the sample code will 
+sometimes deadlock indefinitely around the lock(procedureLock)/Monitor calls.
+
+This bug was discovered while trying to figure out why MySQL connector/NET doesn't work under 
+OS X.


More information about the mono-bugs mailing list