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程序,然後使用命令行方式運行,結果都一樣)打印輸出如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章