Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不断运行python脚本,通过终端调用函数_Python_Networking - Fatal编程技术网

不断运行python脚本,通过终端调用函数

不断运行python脚本,通过终端调用函数,python,networking,Python,Networking,我从来都不确定的快速问题是否可能:3 我有一个python脚本,一个连接到服务器并保持连接的网络脚本,直到我断开连接或它踢我(通常不应该这样),它不断地接收数据并执行其他任务 我很好奇,在脚本运行时,是否有可能从脚本中触发函数?比如说,在脚本运行时,如果我有向服务器发送某种数据的冲动,我可以键入数据并将其发送给处理此问题的函数 我不太确定这是否可能,因为我从未尝试过,甚至从未见过这样做。如果有帮助的话,我正在Ubuntu linux上从终端运行脚本。没有更多细节,我只能为您提供一般的想法。为了同

我从来都不确定的快速问题是否可能:3

我有一个python脚本,一个连接到服务器并保持连接的网络脚本,直到我断开连接或它踢我(通常不应该这样),它不断地接收数据并执行其他任务

我很好奇,在脚本运行时,是否有可能从脚本中触发函数?比如说,在脚本运行时,如果我有向服务器发送某种数据的冲动,我可以键入数据并将其发送给处理此问题的函数


我不太确定这是否可能,因为我从未尝试过,甚至从未见过这样做。如果有帮助的话,我正在Ubuntu linux上从终端运行脚本。

没有更多细节,我只能为您提供一般的想法。为了同时完成两件事(从服务器下载并等待数据发送),您需要使用多个线程或进程。有一个教程,其中有一些多线程的示例。如果您使用多个进程,那么您将使用该包


无论使用哪种解决方案,您都需要类似的设置。其余部分我将使用thread这个术语,但是如果您使用多个进程,您可以很容易地将其替换为process。您可能(至少)有一个线程来发送和接收数据(这可能是两个线程),还有一个单独的线程来等待发送。这是一个简化的示例。等待命令/数据的线程将是一个简单的输入循环,生成要发送的数据,而发送数据的线程将在将数据发送到服务器时使用数据。

没有更多详细信息,我只能为您提供一般思路。为了同时完成两件事(从服务器下载并等待数据发送),您需要使用多个线程或进程。有一个教程,其中有一些多线程的示例。如果您使用多个进程,那么您将使用该包


无论使用哪种解决方案,您都需要类似的设置。其余部分我将使用thread这个术语,但是如果您使用多个进程,您可以很容易地将其替换为process。您可能(至少)有一个线程来发送和接收数据(这可能是两个线程),还有一个单独的线程来等待发送。这是一个简化的示例。等待命令/数据的线程将是一个简单的输入循环,生成要发送的数据,而发送数据的线程将在将数据发送到服务器时使用数据。

将服务器的内容放在另一个线程中(研究
线程
模块)并使用主线程通过
raw_input
/
input
将服务器内容粘贴到另一个线程中与用户进行交互(研究
线程
模块)并使用主线程通过
raw_input
/
input
与用户进行交互。解决此类问题的常用“UNIX方法”是在套接字和标准输入文件描述符上进行交互。然后在套接字上处理“IN”事件上的网络输入,在
stdin
文件描述符上处理“IN”事件上的终端输入


这对于Windows来说是不可移植的(这很糟糕),但这是在类UNIX系统上实现这一点最自然的方式。而且你不会遇到线程所带来的所有问题(通常也需要用Python进行轮询,否则它们会变得“无法解决”。

解决此类问题的常用“UNIX方法”是在套接字和标准输入文件描述符上进行轮询。然后在套接字上处理“IN”事件上的网络输入,在
stdin
文件描述符上处理“IN”事件上的终端输入

这对于Windows来说是不可移植的(这很糟糕),但这是在类UNIX系统上实现这一点最自然的方式。而且你不会遇到线程带来的所有问题(通常也需要在Python中进行轮询,否则它们会变得“无法解决”。

看一下:

gevent是一个基于协同路由的Python网络库,它使用 greenlet在 libevent事件循环

和。

看看:

gevent是一个基于协同路由的Python网络库,它使用 greenlet在 libevent事件循环


而且。

雅切克·科尼茨尼的解决方案既好又简单。如果您想要更灵活的消息传递,请考虑。这使您能够轻松地围绕主程序创建各种消息传递解决方案。使用单个线程,您的主程序将如下所示:

#!/usr/bin/env python

import zmq
from time import sleep

CTX = zmq.Context()

incoming = CTX.socket(zmq.PULL)
incoming.bind("tcp://127.0.0.1:3000")

outgoing = CTX.socket(zmq.PUB)
outgoing.bind("tcp://127.0.0.1:3001")

# Poller for the incoming messages
poller = zmq.Poller()
poller.register(incoming, zmq.POLLIN)

def main():
    while True:
        # Do things on the network
        print("[Did things on the network]")
        # Send messages if you want
        outgoing.send("Important message")
        # Poll for incoming messages
        socks = dict(poller.poll(zmq.NOBLOCK))
        if incoming in socks and socks[incoming] == zmq.POLLIN:
            message = incoming.recv()
            # Handle message
            print("[Handled message '%s']" % message)

        sleep(1) # Only for this dummy program

if __name__ == "__main__":
    main()
然后,您将编写一个客户机(使用具有ZeroMQ绑定的任何语言)来推送和订阅来自主程序的消息。示例推送器:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

pusher = CTX.socket(zmq.PUSH)
pusher.connect("tcp://127.0.0.1:3000")

def main():
    pusher.send("Message to main program")

if __name__ == "__main__":
    main()
订户示例:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

subscriber = CTX.socket(zmq.SUB)
subscriber.connect("tcp://127.0.0.1:3001")
subscriber.setsockopt(zmq.SUBSCRIBE, "")

def main():
    while True:
        msg = subscriber.recv()
        print("[Received message] %s" % msg)

if __name__ == "__main__":
    main()
听起来您可能希望将推送程序和订户程序合并为一个。如果您决定使用ZeroMQ,请查看


当然,您也可以将ZeroMQ与多个线程或进程一起使用(注意不要在线程之间共享单个ZeroMQ套接字)。

Jacek Konieczny的解决方案既好又简单。如果您想要更灵活的消息传递,请考虑。这使您能够轻松地围绕主程序创建各种消息传递解决方案。使用单个线程,您的主程序将如下所示:

#!/usr/bin/env python

import zmq
from time import sleep

CTX = zmq.Context()

incoming = CTX.socket(zmq.PULL)
incoming.bind("tcp://127.0.0.1:3000")

outgoing = CTX.socket(zmq.PUB)
outgoing.bind("tcp://127.0.0.1:3001")

# Poller for the incoming messages
poller = zmq.Poller()
poller.register(incoming, zmq.POLLIN)

def main():
    while True:
        # Do things on the network
        print("[Did things on the network]")
        # Send messages if you want
        outgoing.send("Important message")
        # Poll for incoming messages
        socks = dict(poller.poll(zmq.NOBLOCK))
        if incoming in socks and socks[incoming] == zmq.POLLIN:
            message = incoming.recv()
            # Handle message
            print("[Handled message '%s']" % message)

        sleep(1) # Only for this dummy program

if __name__ == "__main__":
    main()
然后,您将编写一个客户机(使用具有ZeroMQ绑定的任何语言)来推送和订阅来自主程序的消息。示例推送器:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

pusher = CTX.socket(zmq.PUSH)
pusher.connect("tcp://127.0.0.1:3000")

def main():
    pusher.send("Message to main program")

if __name__ == "__main__":
    main()
订户示例:

#!/usr/bin/env python

import zmq

CTX = zmq.Context()

subscriber = CTX.socket(zmq.SUB)
subscriber.connect("tcp://127.0.0.1:3001")
subscriber.setsockopt(zmq.SUBSCRIBE, "")

def main():
    while True:
        msg = subscriber.recv()
        print("[Received message] %s" % msg)

if __name__ == "__main__":
    main()
听起来您可能希望将推送程序和订户程序合并为一个。如果您决定使用ZeroMQ,请查看


当然,您也可以将ZeroMQ与多个线程或进程一起使用(注意不要在线程之间共享单独的ZeroMQ套接字)。

如果需要,我可以共享代码,但这听起来很精确