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,一经查实,立即删除!

相关文章

Java八股文总结四

集合类 一、什么是集合以及使用的好处&#xff1f;Java有哪些常见的集合类&#xff1f; 集合概念 集合就是一个放数据的容器&#xff0c;准确的说是放数据对象引用的容器 集合类存放的都是对象的引用&#xff0c;而不是对象的本身 集合类型主要有3种&#xff1a;set(集&…

Java语言程序设计基础篇_编程练习题*18.8 (以逆序输出一个整数中的数字)

目录 *18.8 (以逆序输出一个整数中的數字) 代码示例 输出结果 *18.8 (以逆序输出一个整数中的數字) 编写一个递归方法&#xff0c;使用下面的方法头在控制台上以逆序显示一个 int 型的值: public static void reverseDisplay(int value) 例如&#xff0c;reverseDisplay(1…

HTTP状态码304

304状态码的那些事 前言定义产生的原因304状态码出现过多会造成的问题状态码3XX&#xff08;重定向&#xff09; 前言 往往在我们开发中&#xff0c;有时候会遇到304状态码&#xff0c;很多的时候我们把他当作一个错误处理&#xff0c;那现在来聊聊这个304是怎么个事 定义 3…

【网络安全】URL解析器混淆绕过CSP实现XSS

未经许可,不得转载。 文章目录 前言正文前言 许多流行的静态网站生成器都存在图像 CDN 功能,它们通过优化网站中的图像来加快页面加载速度。例如: 1、Optimizing Images | Next.js 利用内置的 next/image 组件优化图像(nextjs.org) 2、Nuxt Image: Nuxt 应用的图像优化…

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库开发的时候出…

C++ 生产者-消费者模式详细解析与代码实现

在多线程编程中&#xff0c;生产者-消费者&#xff08;Producer-Consumer&#xff09;模式是一种经典的并发模型。它能够解决多线程环境下资源共享和任务调度的问题。本篇博客将从生产者-消费者模式的概念、实现方式、典型场景、以及具体的C代码示例展开详细讲解。 一、生产者…

声音克隆工具CosyVoice

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

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

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

以编程方式运行仿真

可以通过两种方法以编程方式仿真模型&#xff1a; 通过 sim 命令。 通过运行按钮 使用 sim 命令执行仿真时&#xff0c;可以使用命令行对仿真执行操作。使用运行按钮执行仿真意味着您可以使用 Simulink UI 与仿真进行交互&#xff0c;以执行任何其他操作。下表详细说明了这两…

STM32G474之DAC

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

使用PyTorch Lightning力量精简空间分析

大家好&#xff0c;随着人工智能热潮的全面兴起&#xff0c;PyTorch Lightning库正在获得越来越多的关注。其特别突出的地方在于简化复杂的机器学习操作&#xff0c;即使对于非开发者也是如此。深度学习和部分机器学习中的许多挑战性方面&#xff0c;如多GPU训练和实验跟踪&…

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

物料主数据分布在设计、工艺、生产、采购、销售、存储、物流过程中的多个业务部门中&#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;熬夜…