1

我遇到了应用程序消息传递的问题,......经过一些问答后,我去使用 Remoting 命名空间,在 System.Runtime 命名空间下......

它工作得很好,但问题是当应用程序异常终止时......如果服务器以非方式停止,我注册的频道将保持注册状态,......

我对远程处理或其他相关问题知之甚少……但我检查了一些东西,但没有奏效……

我通过这种方式完成注册的文章,并没有取消注册应用程序,我在服务中使用它,并且似乎服务应用程序主机不会在服务开始停止时关闭......

这是我在服务应用程序中使用的客户端类...

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Remoting
{
    public class Client
    {
        private RemotableObject remoteObject;

        /// <summary>
        /// Configure Client Class
        /// </summary>
        /// <param name="url">Something like: tcp://localhost:8080/HelloWorld</param>
        public Client(string url)
        {
            TcpChannel chan = new TcpChannel();
            ChannelServices.RegisterChannel(chan);

            remoteObject = (RemotableObject)Activator.GetObject(typeof(RemotableObject), url);
        }


        public void SetMessage(string message)
        {
            remoteObject.SetMessage(message);
        }
    }
}

正如我所注意到的,这篇文章没有向频道提供任何信息,所以我想知道取消注册它我应该如何找到它.....

在服务器APP中,文章最后完成了givin host post

using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Remoting
{
    public abstract class Server:IObserver
    {
        private RemotableObject remotableObject;

        /// <summary>
        /// Configure Server Class
        /// </summary>
        /// <param name="port">port number like: 8080</param>
        /// <param name="url">Object url like: HelloWorld</param>
        public Server(int port, string url)
        {
            remotableObject = new RemotableObject();

            TcpChannel channel = new TcpChannel(port);
            ChannelServices.RegisterChannel(channel);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotableObject), url, WellKnownObjectMode.Singleton);

            Cache.Attach(this);
        }

        public abstract void Notify(string message);
    }
}

但是,即使我知道我在运行具有相同端口号的应用程序的服务器上启动我的应用程序,我也不想取消注册其他应用程序通道......我该怎么办?

顺便说一句,大多数问题是关于注册频道的客户端,没有信息......我如何检测它?并在服务尝试这样做之前取消注册它并以异常终止?

如果有帮助,这是我已经收到的错误:

事件类型:错误
事件源:事件阅读器服务
事件类别:无
事件 ID:0
日期:2012 年8 月 20 日
时间:下午 5:23:14
用户:不适用
计算机:HF-SERVER-PC
描述:
无法启动服务。System.Runtime.Remoting.RemotingException:通道“tcp”已注册。在 System.Runtime.Remoting.Channels.ChannelServices.RegisterChannelInternal(IChannel chnl, Boolean ensureSecurity) 在 System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(IChannel chnl) 在 Remoting.Client..ctor(String url) 在 FileEventReaderService.Services .Logger.EventLogger..ctor(String source, String logName, String url) at FileEventReaderService.EventReader..ctor(String sqlServer, String instance, String IntegratedSecurityType, String username, String password, String dataBase) at FileEventReaderService.EventReaderService.OnStart( System.ServiceProcess.ServiceBase.ServiceQueuedMainCallback(对象状态)处的字符串 [] 参数)

有关详细信息,请参阅 go.microsoft.com/fwlink/... 上的帮助和支持中心。

4

1 回答 1

1

在我的情况下,问题是在同一个实例中多次注册 tcp 通道,所以我创建了一个单例类,并且只设置了一次客户端,而所有其他时间我只是调用了那个实例....

using Remoting;

namespace FileEventReaderService.Services.Remotable
{
    class SingletonClient
    {
        private static SingletonClient _instance = new SingletonClient();
        private Client _client = null;

        public static SingletonClient GetSingletonClient()
        {
            return _instance;
        }

        public Client GetClient()
        {
            return _client;
        }

        public void SetClientConfiguration(string url)
        {
            _client=new Client(url);
        }
    }
}

顺便说一句,如果有人需要找到过程......他可以使用这篇文章: http ://www.timvw.be/2007/09/09/build-your-own-netstatexe-with-c/下载演示来源并使用它...

我也以我自己的方式编辑它,你可以使用它:(我没有改变 2 个主类 'TcpTable' 和 'IpHelper')

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Net.NetworkInformation;
using System.Net;
using System.Diagnostics;
using System.Collections;
using System.IO;

namespace FileEventReaderUI.Services.Network
{
    class NetworkInformation
    {
        public ListenerProcessInformation GetListenerProcessInformationByPort(int port)
        {
            string fileName;
            List<string> processModules=new List<string>();

            foreach (TcpRow tcpRow in ManagedIpHelper.GetExtendedTcpTable(true))
            {
                if (tcpRow.LocalEndPoint.Port.ToString(CultureInfo.InvariantCulture).Equals(
                        port.ToString(CultureInfo.InvariantCulture))
                    && tcpRow.State==TcpState.Listen)
                {
                    Process process = Process.GetProcessById(tcpRow.ProcessId);
                    if (process.ProcessName != "System")
                    {
                        foreach (ProcessModule processModule in process.Modules)
                        {
                            processModules.Add(processModule.FileName);
                        }

                        fileName = Path.GetFileName(process.MainModule.FileName);
                    }
                    else
                    {
                        //Console.WriteLine("  -- unknown component(s) --"); ProcessModules count=0
                        //Console.WriteLine("  [{0}]", "System");
                        fileName = "[System]";
                    }

                    return new ListenerProcessInformation(fileName
                                                          , processModules.ToArray()
                                                          , new IPEndPoint(tcpRow.LocalEndPoint.Address,
                                                                         tcpRow.LocalEndPoint.Port)
                                                          , new IPEndPoint(tcpRow.RemoteEndPoint.Address,
                                                                         tcpRow.RemoteEndPoint.Port)
                                                          , tcpRow.ProcessId
                                                          , tcpRow.State);
                }
            }
            return null;
        }
    }

    #region Managed IP Helper API

    public class TcpTable : IEnumerable<TcpRow>
    {
        #region Private Fields

        private IEnumerable<TcpRow> tcpRows;

        #endregion

        #region Constructors

        public TcpTable(IEnumerable<TcpRow> tcpRows)
        {
            this.tcpRows = tcpRows;
        }

        #endregion

        #region Public Properties

        public IEnumerable<TcpRow> Rows
        {
            get { return this.tcpRows; }
        }

        #endregion

        #region IEnumerable<TcpRow> Members

        public IEnumerator<TcpRow> GetEnumerator()
        {
            return this.tcpRows.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.tcpRows.GetEnumerator();
        }

        #endregion
    }

    public class TcpRow
    {
        #region Private Fields

        private IPEndPoint localEndPoint;
        private IPEndPoint remoteEndPoint;
        private TcpState state;
        private int processId;

        #endregion

        #region Constructors

        public TcpRow(IpHelper.TcpRow tcpRow)
        {
            this.state = tcpRow.state;
            this.processId = tcpRow.owningPid;

            int localPort = (tcpRow.localPort1 << 8) + (tcpRow.localPort2) + (tcpRow.localPort3 << 24) + (tcpRow.localPort4 << 16);
            long localAddress = tcpRow.localAddr;
            this.localEndPoint = new IPEndPoint(localAddress, localPort);

            int remotePort = (tcpRow.remotePort1 << 8) + (tcpRow.remotePort2) + (tcpRow.remotePort3 << 24) + (tcpRow.remotePort4 << 16);
            long remoteAddress = tcpRow.remoteAddr;
            this.remoteEndPoint = new IPEndPoint(remoteAddress, remotePort);
        }

        #endregion

        #region Public Properties

        public IPEndPoint LocalEndPoint
        {
            get { return this.localEndPoint; }
        }

        public IPEndPoint RemoteEndPoint
        {
            get { return this.remoteEndPoint; }
        }

        public TcpState State
        {
            get { return this.state; }
        }

        public int ProcessId
        {
            get { return this.processId; }
        }

        #endregion
    }

    public static class ManagedIpHelper
    {
        #region Public Methods

        public static TcpTable GetExtendedTcpTable(bool sorted)
        {
            List<TcpRow> tcpRows = new List<TcpRow>();

            IntPtr tcpTable = IntPtr.Zero;
            int tcpTableLength = 0;

            if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, sorted, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0)
            {
                try
                {
                    tcpTable = Marshal.AllocHGlobal(tcpTableLength);
                    if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0)
                    {
                        IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable));

                        IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length));
                        for (int i = 0; i < table.length; ++i)
                        {
                            tcpRows.Add(new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow))));
                            rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow)));
                        }
                    }
                }
                finally
                {
                    if (tcpTable != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(tcpTable);
                    }
                }
            }

            return new TcpTable(tcpRows);
        }

        #endregion
    }

    #endregion

    #region P/Invoke IP Helper API

    /// <summary>
    /// <see cref="http://msdn2.microsoft.com/en-us/library/aa366073.aspx"/>
    /// </summary>
    public static class IpHelper
    {
        #region Public Fields

        public const string DllName = "iphlpapi.dll";
        public const int AfInet = 2;

        #endregion

        #region Public Methods

        /// <summary>
        /// <see cref="http://msdn2.microsoft.com/en-us/library/aa365928.aspx"/>
        /// </summary>
        [DllImport(IpHelper.DllName, SetLastError = true)]
        public static extern uint GetExtendedTcpTable(IntPtr tcpTable, ref int tcpTableLength, bool sort, int ipVersion, TcpTableType tcpTableType, int reserved);

        #endregion

        #region Public Enums

        /// <summary>
        /// <see cref="http://msdn2.microsoft.com/en-us/library/aa366386.aspx"/>
        /// </summary>
        public enum TcpTableType
        {
            BasicListener,
            BasicConnections,
            BasicAll,
            OwnerPidListener,
            OwnerPidConnections,
            OwnerPidAll,
            OwnerModuleListener,
            OwnerModuleConnections,
            OwnerModuleAll,
        }

        #endregion

        #region Public Structs

        /// <summary>
        /// <see cref="http://msdn2.microsoft.com/en-us/library/aa366921.aspx"/>
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct TcpTable
        {
            public uint length;
            public TcpRow row;
        }

        /// <summary>
        /// <see cref="http://msdn2.microsoft.com/en-us/library/aa366913.aspx"/>
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct TcpRow
        {
            public TcpState state;
            public uint localAddr;
            public byte localPort1;
            public byte localPort2;
            public byte localPort3;
            public byte localPort4;
            public uint remoteAddr;
            public byte remotePort1;
            public byte remotePort2;
            public byte remotePort3;
            public byte remotePort4;
            public int owningPid;
        }

        #endregion
    }

    #endregion
}

以及我用来填充的实体类...

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;

namespace FileEventReaderUI.Services.Network
{
    class ListenerProcessInformation
    {
        private string _fileName;
        private string[] _processModules;
        private IPEndPoint _localEndPoint;
        private IPEndPoint _remoteEndPoint;
        private int _processId;
        private TcpState _state;

        public ListenerProcessInformation(string fileName, string[] processModules, IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, int processId, TcpState state)
        {
            _fileName = fileName;
            _processModules = processModules;
            _localEndPoint = localEndPoint;
            _remoteEndPoint = remoteEndPoint;
            _processId = processId;
            _state = state;
        }

        public string FileName
        {
            get { return _fileName; }
        }

        public string[] ProcessModules
        {
            get { return _processModules; }
        }

        public IPEndPoint LocalEndPoint
        {
            get { return _localEndPoint; }
        }

        public IPEndPoint RemoteEndPoint
        {
            get { return _remoteEndPoint; }
        }

        public int ProcessId
        {
            get { return _processId; }
        }

        public TcpState State
        {
            get { return _state; }
        }
    }
}
于 2012-08-20T19:59:34.677 回答