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.