Multiplexed Socket.Select() problem

Posted on 2003-11-19
Medium Priority
Last Modified: 2013-11-13
In my program, I have a server socket that listens for new connections. When new connection requests arrive, a socket is created for the connection and I add the socket to an arraylist. To process data on these sockets, I execute a multiplex Select() command and pass the arraylist. I am basically looking for all sockets that have data on them waiting to be read. The problem is when I have an arraylist of 65 sockets or more. When I do a Socket.Select on an arraylist of 65 sockets, I get an "index out of bound" error message. I have included my program down below. For testing purposes, I have a client that spawns 100 thread. Each thread is trying to connect and send some data to my component.

using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;

class SelectTcpSrvr
     public static void Main()
          ArrayList sockList = new ArrayList();
          ArrayList copyList = new ArrayList();
          Socket main = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

          IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
          byte[] data = new byte[1024];
          string stringData;
          int recv;


               while (true)
                    if (main.Poll(1000000,SelectMode.SelectRead))
                         Socket client1 = main.Accept();
                         IPEndPoint iep1 = (IPEndPoint)client1.RemoteEndPoint;
                         Console.WriteLine("Connected to {0}", iep1.ToString());

                    if (sockList.Count > 0)
                         copyList = new ArrayList(sockList);
                         Console.WriteLine("Monitoring {0} sockets...", copyList.Count);
                         Socket.Select(copyList, null, null, 10000);
                         foreach(Socket client in copyList)
                              data = new byte[1024];
                              recv = client.Receive(data);
                              stringData = Encoding.ASCII.GetString(data, 0, recv);
                              Console.WriteLine("Received: {0}", stringData);
                              if (recv == 0)
                                   iep = (IPEndPoint)client.RemoteEndPoint;
                                   Console.WriteLine("Client {0} disconnected.", iep.ToString());
                                   if (sockList.Count == 0)
                                        Console.WriteLine("Last client disconnected, bye");
          catch (SocketException ex)
Question by:osalehups
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 3

Expert Comment

ID: 9782924
I don't have any C# experience, but in my experience with select, don't you need to know some information that is returned from the select call?

if it times out you don't want to receive from any of the sockets...
and if a socket becomes available to receive on, don't you want to know which index into the array that you need to receive from?

also, in the Receive call, don' t you need to tell it the max buffer size?

Author Comment

ID: 9783087
The maximum number of sockets that a Windows Sockets application can use is determined at compile time by the manifest constant FD_SETSIZE. This value is used in constructing the FD_SET structures used in select (which I am trying to use). The default value in Winsock2.h is 64. This is why my application fails at 64. If an application is designed to be capable of working with more than 64 sockets, the implementor should define the manifest FD_SETSIZE in every source file before including Winsock2.h. One way of doing this may be to include the definition within the compiler options in the makefile. For example, you could add "-DFD_SETSIZE=128" as an option to the compiler command line for Microsoft C. The thing is how do you do that in c#?


Expert Comment

ID: 9783384
good question... no easy google search has given any hint yet.
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

ID: 9788176
that is why it is a 500 point question ;-)

Expert Comment

ID: 9788738
This is an excerpt that from "Network Programming For Microsoft Windows 2nd Edition" by Anthony Jones and Jim Ohlund that you may want to consider:

The advantage of using select is the capability to multiplex connections and I/O on many sockets from a single thread. This prevents the explosion of threads associated with blocking sockets and multiple connections. The disadvantage is the maximum number of sockets that may be added to the fd_set structures. By default, the maximum is defined as FD_SETSIZE, which is defined in WINSOCK2.H as 64. To increase this limit, an application might define FD_SETSIZE to something large. This define must appear before including WINSOCK2.H. Also, the underlying provider imposes an arbitrary maximum fd_set size, which typically is 1024 but is not guaranteed to be. Finally, for a large FD_SETSIZE, consider the performance hit of setting 1000 sockets before calling select followed by checking whether each of those 1000 sockets is set after the call returns.

I'll continue to see if I find the equivalent for C#

Expert Comment

ID: 9788810
This book also has a .NET Sockets in C# chapter this is an excerpt regarding the usage of Select in C# that may be of interest:  (at least now I understand that the list after the Select only has the sockets needing to be read.. I like that feature)

Select I/O
With the limitations of blocking I/O for managing multiple sockets, .NET Sockets features a Select method that is similar to the Select Winsock 1 API that allows managing multiple socket I/O from one execution thread. Essentially, you can provide Select with a list of sockets to test for readability, writeabilty, and OOB data. The following code fragment demonstrates how to test sockets for readability:

// Assume we have 2 connected sockets - Socket1 and Socket2
Socket[] ReadList = new Socket[2];
ReadList[0] = Socket1;
ReadList[1] = Socket2;

Socket.Select(ReadList, null, null, 100000);

// When Select returns either by our timeout
// value 100000 or if data is pending on one
// of our sockets, the ReadList will contain
// only those sockets that need to be read.
for (int i = 0; i < ReadList.Length; i++)
      byte [] Buffer = new byte[1024];

      // Receive data from the returned socket;
Although Select can manage multiple sockets from a single thread, we highly recommend using our next model—asynchronous—especially if you are developing a high-performance server. For more information about using the Winsock select API, see Chapter 5.

Asynchronous I/O
The asynchronous model in .NET sockets is the best way to manage I/O from one or more sockets. It is the most efficient model of the three because its design is similar to the I/O completion ports model (described in Chapter 5) and on Windows NT–based systems it will use the completion port I/O model internally. Because of this, you can potentially develop a high-performance, scalable Winsock server in C# and even possibly in Visual Basic. For a complete discussion of how to develop a high-performance, scalable Winsock application, see Chapter 6.

In Table 13-2 we described several methods that may be used to process I/O asynchronously: BeginAccept, EndAccept, BeginConnect, EndConnect, BeginReceive, EndReceive, BeginSend, EndSend, BeginSendTo, and EndSendTo. Notice how each one of these methods has a “BeginXXX”-“EndXXX” pair for each of the major I/O-bound socket methods—Accept, Connect, Receive, Send, and SendTo.

To call one of the I/O socket methods asynchronously, you must call the “BeginXXX” method counterpart and supply a delegate (or callback) method in the “BeginXXX” call. When the “BeginXXX” call completes, your calling thread may continue processing other things while your supplied delegate method internally waits for I/O to complete. When the socket has completed your I/O operation, your delegate method is called to process the completed I/O results. Inside your delegate method, you can retrieve the completed I/O results using the EndXXX counterpart method.

For example, let's describe how to process a Receive call asynchronously. We chose Receive because it is one of the most common methods that can cause your application to block when you wait for data to arrive on a socket. To call Receive asynchronously, you must call BeginReceive, which is defined as

public IAsyncResult BeginReceive(
   byte[] buffer,
   int offset,
   int size,
   SocketFlags socketFlags,
   AsyncCallback callback,
   object state
Most of the parameters are similar to the Winsock recv API except for the callback and state parameters. The callback parameter accepts a delegate method that is used to handle the completed results of the asynchronous BeginReceive. The delegate method must have the following form:

public delegate void AsyncCallback(
   IAsyncResult ar
The ar parameter is an input parameter that receives an IAsyncResult object, which you can pass to the EndReceive counterpart method (alternatively, you can use the IAsyncResult object that is returned from the originating BeginReceive call). Also, IAsyncResult contains an important member variable, AsyncState, which contains per-I/O data that was originally passed in the state parameter of the originating BeginReceive call. Typically, you will use this per-I/O data object to pass buffer and socket information that is related to the receive call.

Once your delegate method is called after BeginReceive has completed, you should call EndReceive to retrieve the results of the asynchronous Receive, which is defined as

public int EndReceive(
   IAsyncResult asyncResult
EndReceive returns the number of bytes received in the buffer that was originally passed to BeginReceive. Once you have the completed results, you can begin processing the data received in the buffer.

 When you call BeginReceive, BeginReceiveFrom, BeginSend, or BeginSendTo, you are not allowed to access the supplied buffer until your delegate method has been called indicating that the asynchronous method has completed.

The following code fragment demonstrates how to call Receive asynchronously using BeginReceive and EndReceive. On the companion CD we have provided a sample called TCPServer that demonstrates how to call Accept, Receive, and Send asynchronously on a TCP socket.

// Assume we have a connected socket named MySocket

PerIOData PData;
PData.s = MySocket;

public AsyncCallback AsyncReceiveCallback = new

MySocket.BeginReceive(PData.Buffer, 0, PData.Buffer.Length,
      SocketFlags.None, AsyncReceiveCallback, PData);

public static void ProcessReceiveResults(IAsyncResult ar)
      PerIOData PData = (PerIOData) ar.AsyncState;

      int BytesReceived = PData.s.EndReceive(ar);

   // Do something about your received results
   . . .

public class PerIOData
   // Put whatever data you need here for the delegate method.
   // Most applications will probably define the data buffer
   // here for the received data.
   byte [] Buffer = new byte[4096];
   Socket s;
   . . .


Expert Comment

ID: 9789058
Your code looks like it came from the sample in this book:


Expert Comment

ID: 9789173
That book's author is Rich Blum and he posts avidly on

for example, check these:

your best bet would be to probably go there and post and hope that he answers the question.  Being that he's written this book, he's probably had quite a bit more experience with both the limitations on #s of sockets and the combination of C#.

Author Comment

ID: 9791025
well, if I get an answer from Richard Blum i will give you the points since you suggected it. But I need an answer first. thx

Accepted Solution

jrocnuck earned 2000 total points
ID: 9975754
I just saw this example that looks to use 10000 sockets.  I don't know if it works, but you might find it interesting and worth a try



Expert Comment

ID: 9975772
Also, although the documentation says it's only for older sockets, there is the WSAStartup function that takes the WSAdata structure for C/C++ and it has a member iMaxSockets.  My guess is that it really doesn't do anything, but it's another source of investigation.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A short article about problems I had with the new location API and permissions in Marshmallow
We live in a world of interfaces like the one in the title picture. VBA also allows to use interfaces which offers a lot of possibilities. This article describes how to use interfaces in VBA and how to work around their bugs.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Simple Linear Regression

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question