[Mono-bugs] [Bug 71203][Wis] Changed - Many Socket Methods Fail when > 1024 File descriptors are Open

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Wed, 12 Jan 2005 16:49:41 -0500 (EST)


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 scott@imeem.com.

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

--- shadow/71203	2005-01-12 11:21:33.000000000 -0500
+++ shadow/71203.tmp.19716	2005-01-12 16:49:41.000000000 -0500
@@ -2,13 +2,13 @@
 Product: Mono: Class Libraries
 Version: 1.1
 OS: Red Hat 9.0
 OS Details: 
 Status: NEW   
 Resolution: 
-Severity: 
+Severity: Unknown
 Priority: Wishlist
 Component: CORLIB
 AssignedTo: mono-bugs@ximian.com                            
 ReportedBy: scott@imeem.com               
 QAContact: mono-bugs@ximian.com
 TargetMilestone: ---
@@ -44,6 +44,191 @@
 which provides similar functionality without the limit. Mono should detect at build time whether 
 poll() will be available on the target platform and use it instead of select().
 
 This limit makes it surprisingly hard to write servers which handle thousands of connections (and 
 if you ask any .Net guru they'll chastise you for not using the Async methods - on every mono 
 install I've tried they lock up with > 25 pending operations)
+
+------- Additional Comments From scott@imeem.com  2005-01-12 16:49 -------
+Here's some code which demonstrates the issue (and some others)
+
+using System;
+using System.Collections;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+
+namespace TestMono
+{
+	/// <summary>
+	/// Summary description for Class1.
+	/// </summary>
+	class Class1
+	{
+
+		static int portNo = 9999;
+		static bool keepWorking = false;
+		static ArrayList sockList = new ArrayList();
+
+		/// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		[STAThread]
+		static void Main(string[] args)
+		{
+			//
+			// TODO: Add code to start application here
+			//
+
+			Thread serverThread = new Thread(new ThreadStart(ServerThread));
+			serverThread.Start();
+			Thread connectThread = new Thread(new ThreadStart(ConnectThread));
+			connectThread.Start();
+
+			SelectThread();
+
+		}
+
+
+		static void ServerThread() 
+		{
+
+			Socket sock = new
+Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
+			IPEndPoint iep = new IPEndPoint(IPAddress.Any,portNo);
+			sock.Bind(iep);
+			sock.Listen(500);
+			// workphase1 = other thread connects 
+			keepWorking = true;
+			while (keepWorking) 
+			{
+				Socket newSock = sock.Accept();
+				sockList.Add(newSock);
+				//Console.WriteLine("Server accepting Socket");
+			}
+			Console.WriteLine("closing server Socket");
+			// done test - close them all
+			sock.Close();
+		}
+
+
+		static void ConnectThread() 
+		{
+			for(int i = 0;i<500;i++)
+			{
+				try 
+				{
+					Socket sock = new
+Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
+					IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"),portNo);
+					sock.Connect(iep);
+					if(sock.Connected) 
+					{
+						//Console.WriteLine("Added Socket " + i);
+						sockList.Add(sock);
+					} 
+					else 
+					{
+						Console.WriteLine("Socket " + i + " did not get connected");
+					}
+					Thread.Sleep(10);
+				} 
+				catch (Exception e) 
+				{
+					Console.WriteLine("Socket " + i + " threw exception" +e.ToString());
+				}
+
+			}			
+			keepWorking = false;
+		}
+
+		static void DoSelectTest() 
+		{
+			try 
+			{
+				IList readList = new ArrayList(sockList);
+				//IList writeList = new ArrayList(sockList);
+				//IList errList = new ArrayList(sockList);
+				Socket.Select(readList,null,null,1000000);
+				Console.WriteLine(readList.Count );
+			}
+			catch (Exception e) 
+			{
+				Console.WriteLine("Exception while performing Select() " +
+e.ToString());
+			}
+		}
+
+		static void DoPollTest() 
+		{
+			// first load up a chunk of data on the wire
+			Console.WriteLine("Starting Poll test");
+			foreach (Socket sock in sockList) 
+			{
+				byte[] buffer = new byte[16];
+				sock.Send(buffer);
+			}
+			foreach (Socket sock in sockList) 
+			{
+				try 
+				{
+					if(sock.Poll(0,SelectMode.SelectRead) != true ) 
+					{
+						Console.WriteLine("Poll.Read returned False on socket " +
+sock.Handle.ToString());
+					}
+				} 
+				catch 
+				{
+					Console.WriteLine("Poll.Read threw exception on socket " +
+sock.Handle.ToString());
+				}
+				try 
+				{
+					if(sock.Poll(0,SelectMode.SelectWrite) != true ) 
+					{
+						Console.WriteLine("Poll.Write returned False on socket " +
+sock.Handle.ToString());
+					}
+				} 
+				catch 
+				{
+					Console.WriteLine("Poll.Write threw exception on socket " +
+sock.Handle.ToString());
+				}
+			}
+			Console.WriteLine("Poll test finished");
+		}
+
+		// see if we have a problem when calling select on large numbers of
+sockets
+		static void SelectThread() 
+		{
+			Thread.Sleep(1000);
+			while (keepWorking) 
+			{
+				Console.WriteLine(sockList.Count + " sockets connected");
+				Thread.Sleep(1000);
+			}
+			Console.WriteLine(sockList.Count + " sockets connected");
+			Thread.Sleep(1000);
+			keepWorking = false;
+	
+			// now do something with this mass of sockets
+			DoPollTest();
+
+			Console.WriteLine("Closing Socket List");
+			foreach(Socket sock in sockList) 
+			{
+				try 
+				{
+					sock.Close();
+				} 
+				catch (Exception e) 
+				{
+					Console.WriteLine("Exception while closing socket " + e.ToString());
+				}
+			}
+		}
+
+	}
+}