如果我停止调试服务器程序,.NET Remoting会保留一个侦听套接字

时间:2016-05-23 15:11:25

标签: remoting

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

我有一些Windows服务,它可以监听某些端口(.NET Remoting) 这里是注册频道的代码:

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 [系统]

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

任何想法如何解决?

1 个答案:

答案 0 :(得分:0)

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

您可能还想更改服务,以便明确取消注册频道。我以前编写过使用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并寻找声称等于我的频道参考然后将 传递给“ChannelServices.UnregisterChannel”的参考来避免它们。