简体   繁体   中英

C# Server is not accepting new connections

I have a server that sometimes does not accept new connections. The issue occurs when I open multiple TCP connections but not always.

The server is deployed in multiple remote places (cloud) to test under different RTT. When I open single TCP connection, everything works as expected, but when I try 2 or more TCP connections from the same client to the server (on different ports), the connection fails.

In particular, I have tested with up to 5 TCP connections, locally and by deploying the server on the cloud (with RTT < 5ms) and works, but when the server is located on a server with RTT > 75ms, the connection on the second port most of the time (~90%) is not accepted.

I believe that it has to do with the high RTT, given that this is the only difference between the two locations. Once I set the blocking mode to true, then it works, but I can see that this significantly degrades the performance of the app (due to the blocking).

This the code:

List<Socket> _socket = new List<Socket>();
List<int> _Ports = new List<int> (3) { 48005, 48006, 48007 };

void FunServer ()
{
     for (int ii = 0; ii < _Ports.Count; ii++)
     {
         _socket .Add(new Socket(SocketType.Stream, ProtocolType.Tcp));
         _socket [ii].Blocking = false;
         IPEndPoint _endPoint = new IPEndPoint(IPAddress.Any, _Ports [ii]);
         _socket[ii].Listen(10);
         _socket [ii].Bind(_endPoint);
     }
     Thread _listeningThread = new Thread(this.ListeningFun);
     _listeningThread.IsBackground = true;
     _listeningThread.Start();
}

void ListeningFun()
{
     while (true)
     {
         for (int ii = 0; ii < _Ports.Count; ii++)
         {
             Socket _newClient = null;
             try
             {
                  _newClient = oServerSocket[ii].Accept();
             }                        
             catch (SocketException e)
             {
                  if (e.SocketErrorCode != SocketError.WouldBlock)
                  {
                       \\it never enters here
                  }
                  else
                  {
                       break; // when fails this the error received is: A non-blocking socket operation could not be completed immediately
                  }
             }
             // some other code here ...
         }
         Thread.Sleep(10);
     }
}

If I set the blocking mode to true, it will work, but the performance is lower for the app.

My question is, since I check every 10ms, why can't read the second time (or third etc.)?

I have Wireshark running on both machines, and I can see that the packets arrive on both ports unharmed.

How should I deal with this one? Should I use Async operations?

This is how it worked for me; I modified the code based on Async listener (msdn and the following https://social.msdn.microsoft.com/Forums/en-US/f3151296-8064-4358-98a3-7ecf3d2c474b/multiple-ports-listening-on-c?forum=ncl ):

List<Socket> SocketList = new List<Socket>();
List<int> PortList = new List<int> (3) { 48005, 48006, 48007 };

public class State
{
    public int index = 0;
    public int port;
}

void FunServer ()
{
     for (int ii = 0; ii < PortList.Count; ii++)
     {
          Socket _s = new Socket(SocketType.Stream, ProtocolType.Tcp);
          _s.Blocking = false;
          IPEndPoint _endPoint = new IPEndPoint(IPAddress.Any, PortList[ii]);
          try
          {
              _s.Bind(endPoint); //Associates socket with a local endpoint
              _s.Listen(10);
              State _state = new State();
              _state.index = ii;
              _state.port = PortList[ii];  
              Console.WriteLine("Waiting for a connection...");
              _s.BeginAccept(new AsyncCallback(ListeningFun), _state);
              SocketList.Add(_s);
          }
          catch(Exception e)
          {
          }
     }
}

void ListeningFun(IAsyncResult ar)
{
     var _state = ar.AsyncState as State;
     var _port = state.port;

     try
     {
         Socket _s = SocketList[state.index].EndAccept(ar);
         // some more code here with the _s socket...
     }
     catch (ObjectDisposedException)
     {
         System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
     }
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM