我甚至不确定的快速问题是可能的:3
我有一个python脚本,一个连接到服务器并保持连接的网络脚本,直到我断开连接或它踢我(它通常不应该),这是不断接收数据和执行其他任务。
我很好奇脚本运行时是否一切都可以从脚本中触发函数?在脚本运行时说,如果我有向服务器发送某种数据的冲动,我可以输入它并将其发送到处理这个的函数吗?
不确定是否有可能,因为我从来没有尝试过甚至看过它。如果它有帮助,我在Ubuntu linux上从终端运行脚本。
答案 0 :(得分:1)
解决此类问题的常用“UNIX方式”是套接字和标准输入文件描述符上的poll或select。然后,您可以在stdin
文件描述符上的'IN'事件中的套接字和终端输入上的'IN'事件中处理网络输入。
这不能移植到Windows(这很糟糕),但这是在类UNIX系统上最自然的方式。并且你没有得到线程带来的所有问题(通常也需要在Python中进行轮询,否则它们会变得'不可杀死')。
答案 1 :(得分:1)
答案 2 :(得分:1)
Jacek Konieczny的解决方案很简单。如果您想要更灵活的消息传递,请考虑ZeroMQ。这为您提供了大量功能,可以轻松地围绕主程序创建各种消息传递解决方案。使用单个线程,您的主程序将如下所示:
#!/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,请查看the excellent user guide。
您当然也可以将ZeroMQ用于多个线程或进程(只是注意不要在线程之间共享单个ZeroMQ套接字)。
答案 3 :(得分:0)
如果没有更多细节,我只能为您提供一般性的想法。为了一次做两件事(从服务器下载并等待数据发送),您将需要使用多个线程或进程。有一个包含多个线程here的示例的教程。如果您使用多个流程,则会使用multiprocessing包。
使用任一解决方案,您都需要类似的设置。我会在其余部分使用术语线程,但如果您使用多个进程,则可以轻松地将其替换为进程。你可能(至少)有一个线程来发送和接收数据(这可能是两个线程)和一个单独的线程来等待发送的东西。这是the producer/consumer problem的简化示例。等待命令/数据的线程将是生成要发送的数据的简单输入循环,而发送数据的线程在发送数据时消耗数据服务器。
答案 4 :(得分:0)
将您的服务器内容粘贴到另一个帖子中(调查threading
模块)并使用主线程通过raw_input
/ input
与用户进行互动。