Python进程间网络远程通讯方式:socket、pipe、RPC详解!

背景

最近在进行开发工作的时候,遇到了一个场景:

pc程序需要和安卓设备进行通讯和接口调用。

此时就需要进行远程调用方法。然而大学时代有关于远程过程调用的知识都还给了老师……所以在此进行一个复习,并进行实战演练!

网络远程过程调用

三种方式说明:

  • Socket:主要用于网络通信,它允许不同计算机上的进程通过网络进行数据交换。Socket提供了一个端到端的通信机制,无论是在同一台机器上还是跨网络的不同机器上。
  • Pipe:主要用于同一台机器上的进程间通信(IPC),它实现了一种简单的数据流机制,允许一个进程的输出直接作为另一个进程的输入。Pipe是单向的,数据只能从一个方向流动。
  • RPC:是一种远程过程调用的协议,它允许一个程序通过网络调用另一个地址空间(通常是另一台机器)上的过程(或函数),就像调用本地过程一样。RPC隐藏了网络通信的底层细节,使得远程调用看起来像本地调用一样简单。

相互关系说明:

  • socket和pipe:Socket主要用于跨设备场景,当然也可以用于实现同一台机器上的进程间通信,但是对于同一设备的进程通讯,Pipe更为常见和高效。
  • Socket和RPC:Socket是RPC实现中常用的底层通信机制之一。在RPC框架中,客户端和服务器之间的网络通信通常是通过Socket来完成的。Socket提供了数据传输的通道,而RPC则在这个通道上构建了一个更高层次的调用接口。

方式一:pipe

原理详解:

  • Pipe是一种在Unix和类Unix系统中常用的进程间通信机制。它通过创建一个管道文件来实现数据的单向流动。
  • 当一个进程创建了一个管道时,它会得到两个文件描述符:一个用于写入(写端),另一个用于读取(读端)。写入管道的数据会被存储在内核的缓冲区中,直到被另一个进程读取
  • Pipe的通信是同步的,即写进程在写入数据后会被阻塞,直到读进程读取了数据;同样,读进程在读取数据前也会被阻塞,直到写进程写入了数据

代码示例:

在Windows系统中,Python的multiprocessing模块提供了与Unix系统类似的管道(Pipe)功能,用于进程间通信(IPC)。

from multiprocessing import Process, Pipe  def sender(conn):  conn.send("Hello from sender!")  conn.close()  def receiver(conn):  print("Receiving...")  while True:  try:  data = conn.recv()  print(f"Received: {data}")  except EOFError:  print("No more data. Exiting.")  break  conn.close()  if __name__ == '__main__':  # 创建一个管道  parent_conn, child_conn = Pipe()  # 创建子进程  p1 = Process(target=sender, args=(child_conn,))  p2 = Process(target=receiver, args=(parent_conn,))  # 启动子进程  p1.start()  p2.start()  # 等待子进程完成  p1.join()  p2.join()  

注意:在Windows上,如果接收者进程在发送者进程之后退出,可能会导致发送者进程中的管道连接在关闭时出现问题。  

方式二:socket

原理详解:

  • Socket是计算机网络编程中的一种抽象,它提供了在网络上进行通信的接口。Socket本质上是一种通信的端点,它在网络上标识了一个通信链路的两端,并提供了通信双方所需的接口和功能。
  • 在TCP/IP协议栈中,Socket位于传输层和应用层之间,它使用传输层提供的服务(如TCP或UDP)来实现网络通信。
  • TCP Socket基于TCP协议,提供可靠的、有序的数据传输服务。它通过三次握手建立连接,确保数据的可靠性和顺序性。
  • UDP Socket基于UDP协议,提供简单的数据传输服务,但不保证数据的可靠性和顺序性。它适用于一些实时性要求高、允许一定数据丢失的应用场景。

代码示例:

服务端:
import socket  def tcp_server(host='127.0.0.1', port=12345):  server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  server_socket.bind((host, port))  server_socket.listen(5)  # 最多可以挂起5个连接  print(f"Server is listening on {host}:{port}")  while True:  client_socket, addr = server_socket.accept()  print(f"Connected by {addr}")  try:  while True:  data = client_socket.recv(1024)  if not data:  break  print(f"Received: {data.decode()}")  client_socket.sendall(data)  # Echo back the data  finally:  client_socket.close()  if __name__ == '__main__':  tcp_server()
客户端:
import socket  def tcp_client(host='127.0.0.1', port=12345):  client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  client_socket.connect((host, port))  try:  while True:  message = input("Enter message: ")  if message == 'quit':  break  client_socket.sendall(message.encode())  data = client_socket.recv(1024)  print(f"Received: {data.decode()}")  finally:  client_socket.close()  if __name__ == '__main__':  tcp_client()

方式三:RPC

原理详解:

  • RPC是一种远程过程调用的协议,它允许程序通过网络调用远程地址空间上的过程。RPC隐藏了网络通信的底层细节,使得远程调用看起来像本地调用一样简单。
  • RPC的实现通常包括客户端和服务器两部分。客户端负责发起远程调用请求,并接收服务器返回的调用结果;服务器则负责接收客户端的请求,执行相应的过程,并将结果返回给客户端。
  • RPC框架通常会在客户端和服务器之间建立一条或多条Socket连接,用于传输远程调用的请求和响应。这些Socket连接可以是持久的(长连接),也可以是临时的(短连接)。
  • RPC框架还需要处理一些额外的任务,如参数和结果的序列化与反序列化、网络异常的处理、服务调用的负载均衡等。这些任务通常是由RPC框架本身来完成的,以减轻应用程序的负担。

 

代码示例:

1. .proto 文件(helloworld.proto

这个文件定义了gRPC服务的接口,使用Protocol Buffers语法。

// 使用proto3语法  
syntax = "proto3";  // 定义包名,防止命名冲突  
package helloworld;  // 定义Greeter服务  
service Greeter {  // 定义一个RPC方法SayHello,它接收HelloRequest并返回HelloReply  rpc SayHello (HelloRequest) returns (HelloReply) {}  
}  // 定义HelloRequest消息,包含一个string类型的name字段  
message HelloRequest {  string name = 1; // 字段编号为1  
}  // 定义HelloReply消息,包含一个string类型的message字段  
message HelloReply {  string message = 1; // 字段编号为1  
}
2. Java 服务端实现

这里假设你已经使用protoc编译器和gRPC Java插件生成了GreeterGrpc.javaHelloworld.java等自动生成的代码。

import io.grpc.Server;  
import io.grpc.ServerBuilder;  
import io.grpc.stub.StreamObserver;  
import helloworld.GreeterGrpc;  
import helloworld.GreeterOuterClass;  // 实现GreeterGrpc.GreeterImplBase,提供SayHello方法的具体实现  
public class HelloWorldServer {  static class HelloWorldImpl extends GreeterGrpc.GreeterImplBase {  @Override  public void sayHello(GreeterOuterClass.HelloRequest req, StreamObserver<GreeterOuterClass.HelloReply> responseObserver) {  // 构造回复消息  GreeterOuterClass.HelloReply reply = GreeterOuterClass.HelloReply.newBuilder()  .setMessage("Hello " + req.getName())  .build();  // 发送回复并标记RPC调用完成  responseObserver.onNext(reply);  responseObserver.onCompleted();  }  }  public static void main(String[] args) throws Exception {  // 在指定端口上创建并启动gRPC服务器  Server server = ServerBuilder.forPort(50051)  .addService(new HelloWorldImpl())  .build()  .start();  System.out.println("Server started, listening on 50051");  // 等待服务器终止(通常是通过某种方式发送的关闭信号)  server.awaitTermination();  }  
}
3. Python 客户端实现

这里假设你已经使用protoc编译器和gRPC Python插件生成了__init__.pyhelloworld_pb2.pyhelloworld_pb2_grpc.py等自动生成的代码。

import grpc  import helloworld_pb2  
import helloworld_pb2_grpc  def run():  # 创建一个不安全的通道连接到服务器  with grpc.insecure_channel('localhost:50051') as channel:  # 创建Greeter服务的存根(stub)  stub = helloworld_pb2_grpc.GreeterStub(channel)  # 构造请求消息  response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))  # 打印响应消息  print("Greeter client received: " + response.message)  if __name__ == '__main__':  run()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/52348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE驻网失败问题(三)

这个问题是lab问题&#xff0c;现象如下&#xff1a; 期望UE注册在SA网络下&#xff0c;咋一看没有5G MIB/SIB1打印&#xff0c;好像是没搜到5G小区&#xff0c;而实际上并不是这样。 在查看搜网过程时会发现如下log打印&#xff1a; [I nr5g_rrc_acq.c 3544] RRC ACQ: Band 41…

一个全面、先进、公平且模块化的开源RAG框架

两个关键问题限制了 RAG 的发展&#xff1a; 新型 RAG 算法之间缺乏全面和公平的比较。 像 LlamaIndex 和 LangChain 这样的开源工具使用了高级抽象&#xff0c;这导致了透明度的缺失&#xff0c;并限制了开****发新算法和评估指标的能力。 RAGLAB&#xff1a;是一个模块化的…

QML学习三:qml设计器报错 Line: 0: The Design Mode requires a valid Qt kit

开发环境:Qt 6.5.3 LTS 1、Qt 6.5.3 LTS 2、Pyside6 3、Python 3.11.4 4、win11 默认不打开设计器的时候可以看到我们默认是有Python的环境,而且点击运行是可以运行的。但是当打开qml设计器时提示下面这个错误,提示需要一个可用的套件。 解决办法: 点击+号创建新的套件…

OpenAI官宣ChatGPT用户破2亿,新模型比GPT-4强100倍!

在刚刚召开的“KDDI SUMMIT 2024”大会上&#xff0c;OpenAI日本首席执行官長崎忠雄表示&#xff0c;截止至今年8月底&#xff0c;ChatGPT的月活用户数量突破2亿大关&#xff0c;成为史上最快达到这一成就的软件产品。 同时&#xff0c;ChatGPT企业级用户也获得大幅度增长达到…

Windows自动化程序开发指南

自动化程序的概念 “自动化程序”指的是通过电脑编程来代替人类手工操作的一类程序或软件。这类程序具有智能性高、应用范围广的优点&#xff0c;但是自动化程序的开发难度大、所用技术杂。 本文对自动化程序开发的各个方面进行讲解。 常见的处理对象 自动化程序要处理的对…

STM32关于keil使用过程中遇到的问题

1.设备管理器STlink驱动确认安装完成&#xff0c;但是keil里一直识别不到&#xff0c;换下载器也没用 &#xff08;1&#xff09;问题描述 我的问题是这样产生的&#xff1a;之前用标准库开发STM32的时候&#xff0c;STLink能够正常使用&#xff0c;然后使用HAL库开发的时候出…

声音克隆工具CosyVoice

阿里的免费声音克隆工具CosyVoice CosyVoice 是阿里通义实验室在七月初开源的一款专注于自然语音合成的语音大模型&#xff0c;它具备多语言、多音色和细腻的情感控制能力。这个系统支持中文、英文、日文、粤语和韩语五种语言的语音生成&#xff0c;并且在语音合成的效果上远超…

WebShell流量特征检测_哥斯拉篇

90后用菜刀&#xff0c;95后用蚁剑&#xff0c;00后用冰蝎和哥斯拉&#xff0c;以phpshell连接为例&#xff0c;本文主要是对后三款经典的webshell管理工具进行流量分析和检测。 什么是一句话木马&#xff1f; 1、定义 顾名思义就是执行恶意指令的木马&#xff0c;通过技术手…

STM32G474之DAC

STM32G474分别使用CORDIC硬件和“math.h”的正弦值&#xff0c;从DAC1和DAC2输出。 1、DAC特点 PA4的附加功能为DAC1_OUT1&#xff0c;无需映射&#xff0c;直接将它配置为模拟功能&#xff0c;就可以使用了。 PA6的附加功能为DAC2_OUT1&#xff0c;无需映射&#xff0c;直接将…

物料主数据的分类及编码规则概述

物料主数据分布在设计、工艺、生产、采购、销售、存储、物流过程中的多个业务部门中&#xff0c;类型繁杂且不易于管理&#xff0c;必须对于物料主数据进行分类管理。 本文将从物料主数据的分类原则、编码样例、编码规范以及编码设计等方面进行详细介绍&#xff0c;帮助企业更…

STM32高级定时器生成互补PWM的原理与代码实现

文章目录 前言一 CubeMx配置1.1 TIM1 Mode and Configuration1.2 Paramter Settings 二 程序代码三 仿真分析总结 前言 互补 PWM&#xff08;Complementary PWM&#xff09;是指一对逻辑状态互为反相的 PWM&#xff08;脉冲宽度调制&#xff09;信号。这种信号配置常见于电机控…

数字人实战第三天——wav2lip部署教程

wav2lip数字人 一、wav2lip简介 Wav2Lip 是一种通过将音频与视频中的嘴唇动作同步的技术&#xff0c;旨在生成与音频内容高度匹配的口型动画。其主要应用是让视频中的人物嘴唇动作与配音或其他音频输入精确同步&#xff0c;这在电影配音、虚拟主持人、在线教学、影视后期处理等…

秋招最新大模型算法面试,熬夜都要肝完它

&#x1f4a5;大家在面试大模型LLM这个板块的时候&#xff0c;不知道面试完会不会复盘、总结&#xff0c;做笔记的习惯&#xff0c;这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助&#xff0c;都附有完整答案&#xff0c;熬夜…

CSS —— display属性

用于指定一个元素在页面中的显示方式 HTML中标签元素大体被分为三种类型&#xff1a;块元素、行内元素和行内块元素 块元素 &#xff1a;block 1.独占一行 2.水平方向&#xff0c;占满它父元素的可用空间&#xff08;宽度是父级的100%&#xff09; 3.垂直方向&#xff0c;占据的…

Idea 创建 Maven项目的时候卡死

文章目录 一、Archetype 和 Catalog1.1 Archetype&#xff08;原型&#xff09;1.2 Catalog&#xff08;目录&#xff09; 二、可能遇到的问题2.1 问题描述2.2 原因分析2.3 解决方案 参考资料 一、Archetype 和 Catalog 1.1 Archetype&#xff08;原型&#xff09; Archetype…

【自考zt】【软件工程】【21.10】

关键字&#xff1a; 软件需求基本性质、软件系统需求挑战、耦合&#xff08;高内容&#xff0c;低无直接&#xff09;、内聚&#xff08;初始化时间&#xff09;、uml包、rup边界类、测试首要目标、单元测试最后工作、性能需求 软件开发本质、软件需求规约三种风格、提炼、用…

9.7(QT.Day 1)

一、自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 要求&#xff1a;每行代码都有注释 【需要用到的图片或者动图&#xff0c;自己去网上找】 1.mywidget.h代码 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include <QIcon> //图…

2024全国大学省数学建模竞赛A题-原创参考论文(部分+第一问代码)

一问题重述 1.1 问题背景 "板凳龙"&#xff0c;又称"盘龙"&#xff0c;是浙闽地区的传统地方民俗文化活动。这种独特的表演艺术形式融合了中国传统龙舞的精髓和地方特色&#xff0c;展现了人们对美好生活的向往和对传统文化的传承。 在板凳龙表演中&am…

为elementui的el-date-picker时间选择器添加快捷选项

1、效果图 2、实现方法 直接在elementui的时间选择器上修改&#xff0c;添加shorcuts选项&#xff0c;但是样式要自己修改。 有几个注意点&#xff1a; 1&#xff09;如图我是选中后有显示背景颜色的&#xff0c;也就意味着要给选中的选项添加类名&#xff0c;elementui没有…

一. 从Hive开始

1. 怎么理解Hive Hive不能理解成一个传统意义上的数据库&#xff0c;应该理解成一个解决方案。 是Hadoop在hdfs和mapreduce之后才出现的一个结构化数据处理的解决方案。 Hdfs解决了大数据的存储问题&#xff0c;mapreduce解决了数据的计算问题。 一切似乎很美好。 但是使用成本…