如何在Python中使用socket创建通道

2024-03-16

我之前已经启动过Python几次,现在我正在创建一个套接字服务器。我已经让服务器与多个客户端一起使用多个线程(万岁!)但我正在寻找我无法调用的功能(我什至不知道它是否存在)我想创建一种客户端通道可以发送不同类型的消息。

一个例子,我创建一个通道 INFO,如果服务器收到这种类型的套接字,它只会执行打印

我创建另一个通道 DEBUG,我可以在其中发送服务器将执行的自定义命令

etc

在非编程语言中,它将执行以下操作:

def socketDebug(command):
     run command

def socketInfo(input):
     print input

if socket == socketDebug:
     socketDebug(socket.rcv)
else:
   if socket == socketInfo:
     socketInfo(socket.rcv)

我希望我说清楚了。


这是 Channel 类的一个非常简单的实现。它创建一个套接字,以接受 来自客户端的连接并发送消息。它本身也是一个客户, 从其他 Channel 实例接收消息(例如在单独的进程中)。

通信是在两个线程中完成的,这非常糟糕(我会使用异步io)。什么时候 收到消息,它调用注册的函数在接收线程中哪个 可能会导致一些线程问题。

每个 Channel 实例都会创建自己的套接字,但它的可扩展性要高得多 具有由单个实例复用的通道“主题”。

一些现有的库提供“通道”功能,例如nanomsg http://nanomsg.org.

这里的代码用于教育目的,如果它可以帮助......

import socket
import threading

class ChannelThread(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)

    self.clients = []
    self.chan_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    self.chan_sock.bind(('',0))  
    _, self.port = self.chan_sock.getsockname()
    self.chan_sock.listen(5)
    self.daemon=True
    self.start()

  def run(self):
    while True:
      new_client = self.chan_sock.accept()
      if not new_client:
        break
      self.clients.append(new_client)

  def sendall(self, msg):
    for client in self.clients:
      client[0].sendall(msg)

class Channel(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)

    self.daemon = True
    self.channel_thread = ChannelThread()

  def public_address(self):
    return "tcp://%s:%d" % (socket.gethostname(), self.channel_thread.port)

  def register(self, channel_address, update_callback):
    host, s_port = channel_address.split("//")[-1].split(":")
    port = int(s_port)
    self.peer_chan_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)   
    self.peer_chan_sock.connect((host, port))
    self._callback = update_callback
    self.start()

  def deal_with_message(self, msg):
    self._callback(msg)

  def run(self):
    data = ""
    while True:
      new_data = self.peer_chan_sock.recv(1024)
      if not new_data:
        # connection reset by peer
        break
      data += new_data
      msgs = data.split("\n\n")
      if msgs[-1]:
        data = msgs.pop()
      for msg in msgs:
        self.deal_with_message(msg)

  def send_value(self, channel_value):
    self.channel_thread.sendall("%s\n\n" % channel_value)

Usage:

流程A中:

c = Channel()
c.public_address()

流程B中:

def msg_received(msg):
  print "received:", msg

c = Channel()
c.register("public_address_string_returned_in_process_A", msg_received)

流程A中:

c.send_value("HELLO")

流程B中:

received: HELLO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Python中使用socket创建通道 的相关文章

随机推荐

  • 将一个范围从一个电子表格复制到另一个电子表格

    我试图将数组的内容从一张工作表 其中数组是通过迭代并推送用户选择的列的选择项来创建的 复制到不同电子表格中的另一张工作表 我遇到了许多关于如何将一个范围从一个电子表格导入到另一个电子表格的问题和答案 但没有一个对我有用 所有问题和答案都返回
  • gnuplot 与 iOS

    这里有人有在 iOS 上使用 gnuplot 的经验吗 我想在 iOS 设备上开发一个科学计算应用程序 并想使用 gnuplot 作为绘图引擎 有什么好的教程可以让我开始学习吗 我有同样的一般问题 快速的谷歌搜索让我找到了以下应用程序 它似
  • Django 多对多交叉过滤

    为了简单起见 假设我只有 2 个模型 书籍 作者 class Author models Model name models CharField max length 100 class Book models Model name mod
  • 如何将两个 div 并排放置并使其占据屏幕的整个宽度?

    我试图将两个 div 放在一起 并让它们都填满屏幕的宽度 理想情况下 我希望它看起来像this https i stack imgur com RVxb2 png 我自己尝试过这样做 但是 div 的宽度最终太大并且显示在两行中 这是我正在
  • 更改 withProgress() 生成的消息框的样式和位置

    The withProgress 函数可以生成一个消息框 指示闪亮的应用程序正在运行 但该消息位于浏览器的右上角 文字尺寸较小 这使得该消息不那么引人注目 所以我想知道有没有什么方法可以改变这个框的样式和位置 以便消息更具有表现力 这是我的
  • 将属性值从属性文件或 xml 文件注入 PreAuthorize(...) java 注释(未解决)

    我在之前的帖子中问过这个问题 Spring Security 的 SpEL 将值从 XML 传递到基于 Java 的 SpEL 配置 https stackoverflow com questions 19625465 spel for s
  • wp_mail wordpress html,样式不适用

    我正在尝试从我的 WordPress 插件发送邮件 但是当我检索它时 它没有样式或图像 我正在这样做
  • 骨干木偶不同的合成视图

    是否可以在 Marionette 中拥有一个复合视图 其中包含不同的项目视图 例如 var myCompositeView Backbone Marionette CompositeView extend template Handleba
  • Spring+WebSocket+STOMP。发送给特定会话的消息(非用户)

    我正在尝试使用我找到的配方在 Spring 框架上设置基本的消息代理here https stackoverflow com questions 34929578 spring websocket sendtosession send me
  • 二进制文件到 SQL 数据库 Apache Camel

    我需要一些关于使用 Camel 将二进制文件从文件夹加载到 MySQL 数据库的方法的指导 基本上我想将 PBX 系统中的语音日志存储到数据库中 包含语音日志的目录将是远程目录 我设计了一个原型 但我不确定这是否真的有效 它有效 但我对设计
  • 我可以使用 Moq 集成在 UnitTests 中访问 Autofac 的全部功能吗

    我的项目 它发生在Orchard http www orchardproject net 虽然我不think这是相关的 使用Autofac https github com autofac Autofac 我正在编写单元测试 其中我想使用以
  • 测试屏幕保护程序是否正在运行或工作区是否已锁定

    在 Mac OS X 上 我知道在 Cocoa 中我可以设置一个观察者来检测未来的屏幕保护程序事件或工作区锁定事件 如下所示 id init if self super init NSDistributedNotificationCente
  • 如何使用 SolrJ 检索“facet_queries”数据

    我没有找到任何方法可以做到这一点 是否可以 Thanks 您可以使用以下方法检索构面查询getFacetQuery 方法 https lucene apache org solr 8 6 1 solr solrj org apache so
  • MS Access - VBA - 创建新的 Excel 工作簿

    我使用以下 VBA 函数读取 Excel 文件并 创建 一个新工作簿以将其另存为 CSV 文件 当我第一次运行这个函数时 效果很好 我是否会再次运行此函数 它不会打开新的工作簿 没有返回错误 并且我必须关闭 MS Access 然后再次调用
  • 如何在 IIS 6.0 上部署 WCF 服务?

    我完全陌生WCF和部署服务 我在 IIS 6 0 上设置服务时遇到问题 我需要部署我的确切步骤WCFIIS 6 0 上的服务 注意 我创建了一个WCF服务申请 那么 在 IIS 6 0 上部署 wcf 服务需要遵循哪些具体步骤 我相信你基本
  • 当我在 gridview 中进行排序时,会触发 Gridview RowCommand 事件

    我陷入了一些不正常的问题 当我在 gridview 中进行排序时 它会触发该网格的 RowCommand 事件而不是排序事件 下面是我的网格视图的 HTML 代码
  • Date_format 转换是在边界日期上添加 1 年

    当我使用 DATE FORMAT 表示 12 月 31 日的日期时 2018 年即将更改为 2019 年 有人可以帮忙说这是一个错误还是我遗漏了一些东西 import org apache spark sql functions spark
  • Google App Engine 适用于长时间运行但 CPU 较低的任务,还是长时间轮询?

    App Engine 非常适合快速处理请求 无需对数据库或缓存或第三方资源进行外部 API 调用 但我们发现引入任何类型的 运行时间较长 的组件或外部延迟 例如在 HTTP POST 中 在后台异步运行的操作 可能需要一两秒钟来处理一些更密
  • Facebook 评论插件 Angularjs

    在我的 AngularJS 应用程序中添加 facebook 评论插件时 我遇到了一个奇怪的错误 应用程序页面的简化结构是 div div div div 带有fb评论框的页面被加载到ng view中 包含fb评论框的页面结构如下 div
  • 如何在Python中使用socket创建通道

    我之前已经启动过Python几次 现在我正在创建一个套接字服务器 我已经让服务器与多个客户端一起使用多个线程 万岁 但我正在寻找我无法调用的功能 我什至不知道它是否存在 我想创建一种客户端通道可以发送不同类型的消息 一个例子 我创建一个通道