C#远程调用python(简称RPC)

以前都是使用C#调用webservice服务或者wcf服务,由于特殊需求,需要调用python进行处理,大概流程是:客户端使用C#,服务端使用python,客户端发起调用,服务器执行,服务端执行后把结果返回给客户端

通信的桥梁可以使用XMLRPC

2019年12月9日修改:

注意:如果把python代码运行在远程的服务器上,需要把下面的服务端的python代码中的代码server = SimpleXMLRPCServer(('localhost',666))改为

server = SimpleXMLRPCServer(("",666), allow_none=True),不然会出现客户端无法连接服务器的情况

本人测试使用的vs版本是vs2012

准备工作:

1  C#开发的工具

2  安装python

3  需要下载CookComputing.XmlRpcV2.dll库

不过我发现官网(fanqiang了也不行,敏感字眼居然审核不给通过)和Nuget(可能是我vs的问题)都无法下载,不过我还是把地址贴出来

官网地址:http://www.xml-rpc.net/

Nuget地址:https://www.nuget.org/packages/xmlrpcnet

网盘地址:链接:https://pan.baidu.com/s/1wj05WR8-RNsW4qjAoHfWfA     提取码:08nw 

服务端的python代码(参考别人写的)如下:

from  xmlrpc.server import SimpleXMLRPCServer
 
def getHelloWorld():
    return 'Hello world'
 
if __name__ == '__main__' :
    server = SimpleXMLRPCServer(('localhost',666))
    server.register_function(getHelloWorld, "getHelloWorld")
    server.serve_forever()

客户端C#代码如下(注意要添加CookComputing.XmlRpcV2.dll的引用):

using CookComputing.XmlRpc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpCallPython
{
    class Program
    {
        static void Main(string[] args)
        {
            ProxyInterface proxy = (ProxyInterface)XmlRpcProxyGen.Create(typeof(ProxyInterface));

            Console.WriteLine(proxy.getHelloWorld());
            Console.ReadLine();
        }
    }
}


[XmlRpcUrl("http://localhost:666")]
public interface ProxyInterface : IXmlRpcProxy
{
    [XmlRpcMethod("getHelloWorld")]
    string getHelloWorld();
}

使用cmd运行python服务端,如下图:

运行客户端,结果如下图:

更新于2019年12月9日

例子2:客户端发送图片到服务器,服务器保存图片

服务端的pthon代码如下:

import base64
from  xmlrpc.server import SimpleXMLRPCServer


def zi_tu(b_tu):

    tu_b = base64.b64decode(b_tu)
    with open('C:\\Users\\Administrator\\Desktop\\tu.png', 'wb') as fp:
        fp.write(tu_b)


def getHelloWorld(b_tu):
    zi_tu(b_tu)
    return 'Hello world'
 
if __name__ == '__main__' :
    server = SimpleXMLRPCServer(("",666), allow_none=True)
    server.register_function(getHelloWorld, "getHelloWorld")
    server.serve_forever()

客户端C#代码如下(注意要添加CookComputing.XmlRpcV2.dll的引用和在工程目录的bin/Debug的目录下放一张名为test.png的图片,同时还需要修改ip地址为你的ip地址):

using CookComputing.XmlRpc;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpCallPython
{
    class Program
    {
        static void Main(string[] args)
        {
            ProxyInterface proxy = (ProxyInterface)XmlRpcProxyGen.Create(typeof(ProxyInterface));

            //Console.WriteLine(proxy.getHelloWorld());
            FileStream fs = File.OpenRead("test.png"); //OpenRead
            int filelength = 0;
            filelength = (int)fs.Length; //获得文件长度 
            Byte[] image = new Byte[filelength]; //建立一个字节数组 
            fs.Read(image, 0, filelength); //按字节流读取 
            string ImageString=Convert.ToBase64String(image);
            try
            {
                Console.WriteLine(proxy.getHelloWorld(ImageString));
            }
            catch (Exception ex)
            {
                Console.WriteLine("发生异常");
               
            }
            Console.ReadLine();
        }
    }
}


[XmlRpcUrl("http://47.94.102.147:666")]
public interface ProxyInterface : IXmlRpcProxy
{
    [XmlRpcMethod("getHelloWorld")]
    string getHelloWorld(string imageString);
}

更新于2019年12月17日

例子3   C#客户端发送图片,python服务端转成可以使用opencv-python操作的对象

C#客户端的程序同例子2

python服务器程序编写如下:

注意:操作前python服务器需要安装python对应版本的opencv-python库

import base64
from  xmlrpc.server import SimpleXMLRPCServer
import cv2
import numpy as np
def zi_tu(b_tu):
    tu_b = base64.b64decode(b_tu)
    #字节数组转换成numpy可以处理的数组
    imga = np.frombuffer(tu_b, np.uint8)
    #解码数组,获取opencv-python可以处理的图片对象
    img = cv2.imdecode(imga,cv2.IMREAD_COLOR)
    #显示图片
    cv2.imshow("Image",img)
    #等待,不然程序一下就过去了,显示的图片你会看不到
    cv2.waitKey(0)
    #打印输出,看一下图片对象的值
    print(img)

def getHelloWorld(b_tu):
    zi_tu(b_tu)
    return 'Hello world'
 
if __name__ == '__main__' :
    server = SimpleXMLRPCServer(("",666), allow_none=True)
    server.register_function(getHelloWorld, "getHelloWorld")
    server.serve_forever()

效果如下:

1    python服务器图片对话框如果不关闭,效果如下图:

2  python服务器图片对话框关闭后,效果如下图:

并且可以看到jupyter  notebook(我使用jupyter notebook编写的python程序,当然你也可以使用记事本编写python程序,然后使用命令行方式运行,结果都一样)打印输出如下:

发布了66 篇原创文章 · 获赞 48 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/zxy13826134783/article/details/102977028