python-rpc-windows服务器C#项目远程调用Linux服务器上的python脚本

8,457次阅读
没有评论

共计 2753 个字符,预计需要花费 7 分钟才能阅读完成。

环境:
win10,Python 3.9.13

参考:
Python3 简单使用 xmlrpc 实现 RPC – 简书
https://www.jianshu.com/p/9987913cf734


目录

  • 问题描述
  • 解决
    • 思路
    • server
    • client
    • debug
      • 对方服务器积极拒绝

问题描述

之前写过:
c#远程调用 linux 服务器的 Python 脚本_c# 远程登录其他服务器执行脚本 -CSDN 博客
https://blog.csdn.net/pxy7896/article/details/121473815

pythonnet-C# 调用 python 脚本 - 含 matplotlib+biopython_c# pythonnet 调用 python 脚本 -CSDN 博客
https://blog.csdn.net/pxy7896/article/details/141608138

目前遇到的问题是:

  1. 同事那边是 windows 系统、.net 项目,她需要调用我这边 linux 服务器上的一个 python 脚本
  2. 该脚本涉及比较多的数据和程序,不方便挪动;同时,该脚本接收一个 txt 文件作为输入,处理后产生一个 zip 文件作为输出
  3. 使用远程调用的话,需要考虑文件的上传和下载功能

解决

思路

在 linux 和 windows 上分别实现 server 和 client,.net 项目里使用 pythonnet 调用 client 里的函数。

server



from xmlrpc.server import SimpleXMLRPCServer
from socketserver import ThreadingMixIn
import xmlrpc.client
import base64

class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
    pass

def file_output(name):
    '''
    下载文件
    name: 唯一标识符
    '''
    file_name = os.getcwd() + "/" + name
    if not os.path.isfile(file_name):
        return f"Error: File'{name}'does not exist."
    with open(file_name, 'rb') as file:
        return file.read()

def file_input(filename, filedata):
	'''
    上传文件
    file_name: 唯一标识符
    file_data: byte 数据
    '''
    with open(filename, 'wb') as file:
        file.write(base64.b64decode(filedata))
    
    return f"File {filename} saved successfully."

if __name__ == '__main__':
    server = ThreadXMLRPCServer(('IP', 端口), allow_none=True) 
    server.register_function(file_input, 'file_input')
    server.register_function(file_output, 'file_output')
    print("Listening for Client")
    server.serve_forever() 

如果只需要传数据,不需要传文件名,也可以这样写:


def file_input(data):
    handle = open("xxx.txt", 'wb')
    handle.write(data.data)
    handle.close()

client



from xmlrpc.client import ServerProxy
import xmlrpc.client
import base64
import os

server_url = "http://IP: 端口"

def send_file(file_path):
    with open(file_path, 'rb') as file:
        filedata = file.read()
    file_name = os.path.basename(file_path)
    
    filedata_b64 = base64.b64encode(filedata).decode('utf-8')
    
    with ServerProxy(server_url) as proxy:
        response = proxy.file_input(file_name, filedata_b64)
        print(response)

def get_file(name):
    save_path = os.path.join(os.getcwd(), name + ".zip")
    with ServerProxy(server_url) as proxy:
        file_content = proxy.file_output(name)
        if not isinstance(file_content, str):
            with open(save_path, 'wb') as file:
                file.write(file_content.data)
            print("ok")
        else:
            print(file_content)  

if __name__ == '__main__':
	
    file_path = "文件路径"
    send_file(file_path)
    
    
    zip_prefix = "test"
    get_file(zip_prefix)
    

如果是第二种 file_input 写法,那么对应的上传这样写:

server = ServerProxy("http://IP: 端口", allow_none=True)
put_handle = open("路径", 'rb')
server.file_input(xmlrpc.client.Binary(put_handle.read()))
put_handle.close()

注意:client 端写文件时需要使用 file.write(file_content.data),因为file_content 不是 byte。可以用type() 打印一下,结果是:

class 'xmlrpc.client.Binary'>

debug

对方服务器积极拒绝

检查:

  1. 能否 ping 通
    不过不通的话应该报错:
    TimeoutError: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。
  2. 服务器端口是否开放
  3. 服务器程序是否正常运行
  4. server 这句是不是写成 localhost。应该写对外的 IP
    server = ThreadXMLRPCServer(('IP', 端口), allow_none=True) 
    

最后再检查防火墙。不过一般前几个搞定就好了。

原文地址: python-rpc-windows 服务器 C# 项目远程调用 Linux 服务器上的 python 脚本

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-30发表,共计2753字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)