Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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# 通过套接字动态调用方法_C#_Sockets_Reflection_Methods_Invoke - Fatal编程技术网

C# 通过套接字动态调用方法

C# 通过套接字动态调用方法,c#,sockets,reflection,methods,invoke,C#,Sockets,Reflection,Methods,Invoke,我有两台装有软件的电脑,现在我需要一台电脑在另一台电脑上执行一个方法,现在我到处搜索,但找不到任何关于如何执行的信息。我可以通过编写自己的小接口来实现这一点,该接口序列化参数、方法名和返回对象,并通过套接字发送这些参数,然后反序列化这些参数,使用反射执行方法,并通过套接字返回结果对象。但在我开始用另一种更简单的方式写东西之前,我想听听别人的意见 发送多个参数(它们都将作为对象接收和发送) 返回一个对象 如果发生异常,则序列化回异常对象 我在序列化对象并通过套接字发送它们方面没有做过任何工作,

我有两台装有软件的电脑,现在我需要一台电脑在另一台电脑上执行一个方法,现在我到处搜索,但找不到任何关于如何执行的信息。我可以通过编写自己的小接口来实现这一点,该接口序列化参数、方法名和返回对象,并通过套接字发送这些参数,然后反序列化这些参数,使用反射执行方法,并通过套接字返回结果对象。但在我开始用另一种更简单的方式写东西之前,我想听听别人的意见

  • 发送多个参数(它们都将作为对象接收和发送)
  • 返回一个对象
  • 如果发生异常,则序列化回异常对象
我在序列化对象并通过套接字发送它们方面没有做过任何工作,但是所有的标准对象都可以序列化吗?像
列表数组[]float dateTime


我希望已经解释好了,如果没有,我很抱歉,并询问有什么不清楚。

创建服务WCF并配置WCF以通过TCP工作

这将为您提供大多数“开箱即用”的功能(序列化/反序列化、打开/关闭套接字)


这里有一些很好的示例和阅读资料

创建服务WCF并配置WCF以在TCP上工作

这将为您提供大多数“开箱即用”的功能(序列化/反序列化、打开/关闭套接字)


这里有一些很好的例子,阅读起来也不错,您所描述的内容听起来像是远程过程调用(RPC)。RPC允许您在服务器上创建一个对象,客户端可以像处理本地对象一样与之交互(因此完全避免了处理套接字的需要)。或者,每个客户机也可以创建自己的唯一服务器对象以与之交互

可以在网络库中找到RPC的完整实现。下面的代码片段取自可用的RPC示例,并使用类型为
MathClass
的对象,该对象可以执行简单的数学计算

对象存在于服务器端:

//Register a single object server side called "Calculator"
RemoteProcedureCalls.Server.RegisterInstanceForPublicRemoteCall<MathClass, IMath>(new MathClass(), "Calculator");
//注册一个名为“计算器”的单一对象服务器端
RemoteProcedureCalls.Server.RegisterInstancePerPublicRemoteCall(新的MathClass(),“计算器”);
在客户端:

//Get a reference to the remote object named "Calculator"
IMath calc = RemoteProcedureCalls.Client.CreateProxyToPublicNamedInstance<IMath>(connection, "Calculator", out instanceId);
//We can now use the calculator object as if it were local
//The following WriteLine outputs '12' where the calculation was performed on the server
Console.WriteLine(calc.Multiply(4, 3));
//获取对名为“Calculator”的远程对象的引用
IMath calc=remoteproceduclares.Client.CreateProxyToPublicNamedInstance(连接,“计算器”,out instanceId);
//我们现在可以使用计算器对象,就好像它是本地的一样
//以下WriteLine输出“12”,其中在服务器上执行了计算
控制台写入线(计算乘法(4,3));

免责声明:我必须补充一点,我是这个库的开发人员。

您所描述的内容听起来像远程过程调用(RPC)。RPC允许您在服务器上创建一个对象,客户端可以像处理本地对象一样与之交互(因此完全避免了处理套接字的需要)。或者,每个客户机也可以创建自己的唯一服务器对象以与之交互

可以在网络库中找到RPC的完整实现。下面的代码片段取自可用的RPC示例,并使用类型为
MathClass
的对象,该对象可以执行简单的数学计算

对象存在于服务器端:

//Register a single object server side called "Calculator"
RemoteProcedureCalls.Server.RegisterInstanceForPublicRemoteCall<MathClass, IMath>(new MathClass(), "Calculator");
//注册一个名为“计算器”的单一对象服务器端
RemoteProcedureCalls.Server.RegisterInstancePerPublicRemoteCall(新的MathClass(),“计算器”);
在客户端:

//Get a reference to the remote object named "Calculator"
IMath calc = RemoteProcedureCalls.Client.CreateProxyToPublicNamedInstance<IMath>(connection, "Calculator", out instanceId);
//We can now use the calculator object as if it were local
//The following WriteLine outputs '12' where the calculation was performed on the server
Console.WriteLine(calc.Multiply(4, 3));
//获取对名为“Calculator”的远程对象的引用
IMath calc=remoteproceduclares.Client.CreateProxyToPublicNamedInstance(连接,“计算器”,out instanceId);
//我们现在可以使用计算器对象,就好像它是本地的一样
//以下WriteLine输出“12”,其中在服务器上执行了计算
控制台写入线(计算乘法(4,3));

免责声明:我必须补充一点,我是这个库的开发人员。

我在互联网上搜索了一些示例并粘贴了一些代码,如果有人也需要的话,我会在这里发布。这是一个脏代码,但它可以工作,InvokeMethod在客户端,startIBC是每个服务器上需要启动的:

[ServiceContract]
    public interface IBlissRequest
    {
        [OperationContract]
        object SystemRequest(string InstanceName, string MethodName, params object[] Parameters);
    }

    public class BlissRequest : IBlissRequest
    {
        public object SystemRequest(string InstanceName, string MethodName, params object[] Parameters)
        {
            return System21.BlissProcessingUnit.BPU.RequestFromIBC(InstanceName, MethodName, Parameters);
        }
    }

public static object InvokeMethod(string targetIpAddress, string InstanceName, string MethodName, params object[] Parameters)
        {
            try
            {
                var ep = "net.tcp://" + targetIpAddress + ":9985/IBC";

                NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);

                ChannelFactory<IBlissRequest> pipeFactory = new ChannelFactory<IBlissRequest>(binding, new EndpointAddress(ep));

                IBlissRequest pipeProxy = pipeFactory.CreateChannel();

                return pipeProxy.SystemRequest(InstanceName, MethodName, Parameters);
            }
            catch 
            {
                BPUConsole.WriteLine(BPUConsole.WriteSource.IBC, "Unable to execute method: '" + MethodName +"' on Instance: '"+InstanceName+"' becouse IBC is unable to connect to: "+ targetIpAddress);
                throw new Exception("Unable to connect to: " + targetIpAddress);
            }
        }

        public static void StartIBC()
        {
            var uri = "net.tcp://" + BlissProcessingUnit.BPUInformation.LocalIpAddresses[0] + ":9985";
            Console.WriteLine("Opening connection on: " + uri);

            ServiceHost host = new ServiceHost(typeof(BlissRequest), new Uri[] { new Uri(uri) });

            NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);

            host.AddServiceEndpoint(typeof(IBlissRequest), binding, "IBC");

            host.Open();

            Console.WriteLine("Service is available. " + "Press <ENTER> to exit.");

        }
[服务合同]
公共接口请求
{
[经营合同]
对象SystemRequest(string InstanceName、string MethodName、params对象[]参数);
}
公共类请求:IBlissRequest
{
公共对象SystemRequest(string InstanceName、string MethodName、params对象[]参数)
{
返回System21.BlissProcessingUnit.BPU.RequestFromIBC(InstanceName、MethodName、Parameters);
}
}
公共静态对象InvokeMethod(字符串targetIpAddress、字符串InstanceName、字符串MethodName、params对象[]参数)
{
尝试
{
var ep=“net.tcp://”+targetIpAddress+“:9985/IBC”;
NetTcpBinding=新的NetTcpBinding(SecurityMode.None);
ChannelFactory pipeFactory=新的ChannelFactory(绑定,新端点地址(ep));
IBlissRequest pipeProxy=pipeFactory.CreateChannel();
返回pipeProxy.SystemRequest(InstanceName、MethodName、参数);
}
抓住
{
BPUConsole.WriteLine(BPUConsole.WriteSource.IBC,“无法在实例:“+InstanceName+””上执行方法:“+MethodName+”,因为IBC无法连接到:“+targetIpAddress”);
抛出新异常(“无法连接到:“+targetIpAddress”);
}
}
公共静态void StartIBC()
{
var uri=“net.tcp://”+BlissProcessingUnit.BPUInformation.LocalIpAddresses[0]+“:9985”;
Console.WriteLine(“在:+uri上打开连接”);
ServiceHost主机=新ServiceHost(typeof(BlissRequest),新Uri[]{newURI(Uri)});
NetTcpBinding=新的NetTcpBinding(SecurityMode.None);