Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TCP侦听器在负载平衡器后面时不工作_C#_Tcp_Load Balancing_Router_Tcplistener - Fatal编程技术网

C# TCP侦听器在负载平衡器后面时不工作

C# TCP侦听器在负载平衡器后面时不工作,c#,tcp,load-balancing,router,tcplistener,C#,Tcp,Load Balancing,Router,Tcplistener,我在windows服务中有一个TCP侦听器,它侦听特定端口上的任何传入TCP请求并处理消息。直接访问时,它工作正常。但是,一旦它在负载平衡器(intranet)后面运行,它就不会接受任何请求。我收到诸如“无法连接到远程服务器”或“操作超时”之类的错误。一段时间后,服务终止,出现“内存不足”异常。请让我知道这可能是什么原因。粘贴下面的代码。我甚至还尝试了异步模式(以避免显式线程启动)。但那没用 public class SampleListener: IDisposable { publi

我在windows服务中有一个TCP侦听器,它侦听特定端口上的任何传入TCP请求并处理消息。直接访问时,它工作正常。但是,一旦它在负载平衡器(intranet)后面运行,它就不会接受任何请求。我收到诸如“无法连接到远程服务器”或“操作超时”之类的错误。一段时间后,服务终止,出现“内存不足”异常。请让我知道这可能是什么原因。粘贴下面的代码。我甚至还尝试了异步模式(以避免显式线程启动)。但那没用

public class SampleListener: IDisposable
{
    public delegate void JobRecieved(HttpMessage msg);
    public event JobRecieved OnJobRecieved;

    #region Property

    private TcpListener _tcpListener;
    private Thread _listenerThread;

    public int Port { get; private set; }

    public string Url
    {
        get
        {
            return new UriBuilder { Scheme = "http", Port = Port, Host = Dns.GetHostName() }.ToString();
        }
    }

    #endregion

    public SampleListener(int port)
    {
        Port = port;
    }

    ~SampleListener()
    {
        DisposeImpl(false);
    }

    public void Start()
    {
        _tcpListener = new TcpListener(IPAddress.Any, Port);
        _tcpListener.Start();

        _listenerThread = new Thread(ListenCallback);
        _listenerThread.Start();
    }

    public void ListenCallback()
    {
        try
        {
            while (true)
            {
                using (TcpClient client = _tcpListener.AcceptTcpClient())
                using (var clientStream = client.GetStream())
                {
                    var msg = new HttpMessage();
                    msg.Receive(clientStream);
                    SendOKResponse(client, "");
                    OnJobRecieved(msg);
                    client.Close();
                }
            }
        }
        catch (System.Net.Sockets.SocketException e)
        {
            // Expected, TcpClient.Stop called                
        }
        catch (System.Threading.ThreadAbortException)
        {
            // Expected, thread going away
        }
        catch (System.IO.IOException)
        {
            // Expected, shutdown while reading
        }
    }

    private void SendOKResponse(TcpClient tcpClient, String responseBody)
    {
        var response = new HttpMessage
        {
            Status = "200",
            Reason = "OK",
            Version = "HTTP/1.1"
        };
        response.Send(tcpClient.GetStream(), responseBody);
    }

    public void Shutdown()
    {
        lock (this)
        {
            if (_listenerThread != null)
            {
                _listenerThread.Abort();
                _listenerThread = null;
            }

            if (_tcpListener != null)
            {
                _tcpListener.Stop();
                _tcpListener.Server.Close();
                _tcpListener = null;
            }                
        }
    }

    #region IDisposable Members

    private void DisposeImpl(Boolean bDisposing)
    {
        lock (this)
        {
            Shutdown();
        }
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
        DisposeImpl(true);
    }

    #endregion

}

这是因为Windows上的NLB需要您的应用程序默认为集群应用程序。如果不是(这是你的情况),你必须使用粘性会话。显然,您的NLB没有使用粘性会话,因此每次传递时请求可能会传输到不同的服务器。这就是为什么会出现这些异常(请看一看)


这发生在我自己的一个项目上(一个高性能TCP服务器,与您正在做的相反)。

根据负载平衡器的类型,可能有几个原因,但负载平衡者很可能不转发端口,因为它根本不知道端口的存在。我同意Joachim的分析。此外,您收到OutOfMemory异常的事实可能表明您的客户端没有正常处理不成功的连接尝试,将对象留在内存中。这可能是一个非常严重的问题。@OnoSendai,如果您看到上面的代码,我将在shutdown方法中处理所有对象。我还尝试了异步实现,这也抛出了内存不足异常,这是除了LB的主要问题之外我面临的另一个问题。感谢您的回复。正如我所说,我尝试将代码更改为异步模式(使用回调)。但我仍然在获取这些内存中的异常。我在这个网站上查看了这个链接,这也建议我去异步,你说我的应用程序需要集群一个。这是什么意思?请解释我已经看完了这篇文章,我没有使用任何会话。每个传入的TCP请求都可以独立处理,而无需维护内存中以前请求的任何状态。所以“无关联”模式适合me1-NLB设置与您的代码没有任何关系。这是关于在同一台服务器上保持TCP连接(对话)和同一个客户端(粘性会话)。否则,您可以在服务器上建立TCP连接,然后客户端对其进行响应,然后NLB将响应发送到另一台服务器(这是平衡部分)。但是你需要在同一台服务器上得到答案(这意味着你需要在负载平衡器上使用粘性会话)。2-你不需要制作集群应用程序,因为这是一种复杂的方式。问题的答案就是在NLB上使用粘性会话。但仅供参考的windows服务可以设计成集群;与IIS或MSMQ类似,这意味着Windows(以及应用程序本身)将负责在不同服务器上同步“状态”(RAM或磁盘中不同参数的值或…)。我希望这有帮助。