【问题标题】:C# Server is not accepting new connectionsC# 服务器不接受新连接
【发布时间】:2019-11-21 01:13:41
【问题描述】:

我的服务器有时不接受新连接。当我打开多个 TCP 连接时会出现此问题,但并非总是如此。

服务器部署在多个远程位置(云端),在不同的RTT下进行测试。当我打开单个 TCP 连接时,一切都按预期工作,但是当我尝试从同一客户端到服务器(在不同端口上)的 2 个或多个 TCP 连接时,连接失败。

特别是,我已经测试了多达 5 个 TCP 连接,本地和通过在云上部署服务器(RTT 75ms 的服务器上时,连接大部分时间 (~90%) 在第二个端口上不被接受。

我认为这与高 RTT 有关,因为这是两个位置之间的唯一区别。一旦我将阻塞模式设置为 true,它就会起作用,但我可以看到这会显着降低应用程序的性能(由于阻塞)。

这是代码:

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);
     }
}

如果我将阻塞模式设置为 true,它会起作用,但应用程序的性能会降低。

我的问题是,既然我每 10 毫秒检查一次,为什么不能读取第二次(或第三次等)?

我在两台机器上都运行了 Wireshark,我可以看到数据包都完好无损地到达了两个端口。

我应该如何处理这个问题?我应该使用异步操作吗?

【问题讨论】:

  • 异步可能会让事情变得更容易。您可以设置为等待连接并在事件发生时获取。
  • @SamiKuhmonen 谢谢,我会用异步试试看

标签: c# sockets networking


【解决方案1】:

这对我来说是这样的;我修改了基于Async listener的代码(msdn和下面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");
     }
}


【讨论】:

    猜你喜欢
    • 2013-09-17
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    相关资源
    最近更新 更多