【问题标题】:.NET Remoting keeps a listening socket if I stop debugging server program如果我停止调试服务器程序,.NET Remoting 会保留一个侦听套接字
【发布时间】:2016-05-23 15:11:24
【问题描述】:

我有零星的问题,并不总是发生。

我有侦听某个端口(.NET Remoting)的 Windows 服务。
这里是注册频道的代码:

void RegisterChannel(int portNumber, string bindTo)
{
    ListDictionary channelProperties = new ListDictionary();
    channelProperties.Add("name", Guid.NewGuid().ToString().ToUpper());
    channelProperties.Add("port", portNumber);
    channelProperties.Add("bindTo", bindTo);
    channelProperties.Add("secure", true.ToString());
    channelProperties.Add("impersonate", true.ToString());
    channelProperties.Add("useIpAddress", false.ToString());

    BinaryClientFormatterSinkProvider clientFormatter = new BinaryClientFormatterSinkProvider();
    BinaryServerFormatterSinkProvider serverFormatter = new BinaryServerFormatterSinkProvider();
    serverFormatter.TypeFilterLevel = TypeFilterLevel.Full;
    TcpChannel tcpChannel = new TcpChannel(channelProperties, clientFormatter, serverFormatter);

    ChannelServices.RegisterChannel(tcpChannel, true);
}

RegisterChannel(9000, "[::]");
RegisterChannel(9000, "0.0.0.0");
RemotingConfiguration.RegisterWellKnownServiceType(typeof(AccessServer), "AccessLayer", WellKnownObjectMode.Singleton);

如果我在 Visual Studio 中开始调试此服务然后停止调试,之后我将无法开始调试。

我收到以下异常: 每个套接字地址(协议/网络地址/端口)通常只允许使用一次

运行 netstat –anbo 显示:

TCP 0.0.0.0:9000 0.0.0.0:0 LISTENING 3432 [系统]

TCP [::]:9000 [::]:0 LISTENING 3432 [系统]

之后我必须重新启动,否则端口将永远占用。

有什么解决办法吗?

【问题讨论】:

    标签: remoting


    【解决方案1】:

    首先,当你停止调试时,服务进程是否肯定被终止?可以启动调试器,然后在您再次分离后继续进程 - 这意味着服务代码仍将运行,因此仍会占用端口。

    您可能还想更改您的服务,以便明确取消注册频道。我过去编写过使用 Remoting 的 Windows 服务,并且在“OnStart”中配置了 TcpChannel,就像您问题中的代码一样,然后在“OnStop”中通过调用“UnregisterChannel”取消注册该通道 -

    public static void UnregisterChannel(IChannel chan)
    {
        // Due to some weird behaviour we can only remove the registered channel
        // by spinning through the list of channels
        foreach (IChannel ch in ChannelServices.RegisteredChannels)
        {
            if (ch.Equals(chan))
            {
                ChannelServices.UnregisterChannel(ch);
                return;
            }
        }
    }
    

    为此,您需要保留对“tcpChannel”的引用,以便在完成后取消注册。

    您可能认为您可以直接使用您现在持有的 tcpChannel 引用直接调用“ChannelServices.UnregisterChannel”,直到“整理时间”,但我遇到了一些问题 - 我不记得确切的症状是,但我记得通过循环通过 RegisteredChannels 集并寻找声称等于我的频道引用的引用然后将 that 传递给“ChannelServices.UnregisterChannel”来避免它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      • 2018-11-20
      • 1970-01-01
      • 2010-11-09
      相关资源
      最近更新 更多