[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());
+ }
+ }
+ }
+
+ }
+}