gpt4 book ai didi

python - 运行 reactor.run() 后启动 TCP 客户端

转载 作者:太空狗 更新时间:2023-10-30 00:14:30 26 4
gpt4 key购买 nike

我正在尝试制作一个仅用于发送短信的 p2p 应用程序。我这样做的方式是让一个服务器在应用程序运行时一直运行,以及一个连接到其他节点服务器以发送消息的客户端。出于测试目的,我使用本地主机进行测试,即自言自语。

所以我有以下内容:

from twisted.internet import reactor
from mylib import MessageSFactory

def send_message(message):
reactor.connectTCP("localhost", 8080, MessageCFactory(message))

reactor.listenTCP(8080, MessageSFactory())
reactor.connectTCP("localhost", 8080, MessageCFactory("this message gets received"))
reactor.run()

send_message("this message doesn't")

但是问题是在 reactor.run 之后调用 send_message(最后一行)似乎没有效果。

问题是只有当用户填写并发送消息时,我才需要运行 tcp 客户端部分 (connectTCP)。所以我试图通过调用 send_message 来做到这一点。那么我该如何修复上面的代码才能使其正常工作呢?

根据我目前所读到的内容,使用 LoopingCall 是可行的方法,但是我必须将客户端输入的新消息存储到一个变量中,并不断检查该变量是否有新消息消息而不是运行 send_message 这将导致用户输入和函数回调之间的延迟,无论这是我的最佳选择吗?

在这种情况下还有其他方法吗?还是我对twisted 架构的某些关键部分缺乏了解?

编辑:根据要求,这是 GUI 代码,它从客户端获取消息输入:

from Tkinter import *

def send_message():
print("message: %s" % (e1.get()))

master = Tk()
Label(master, text="Message").grid(row=0)
e1 = Entry(master)
e1.grid(row=0, column=1)
Button(master, text='Send', command=send_message).grid(row=3, column=1, sticky=W, pady=4)
mainloop()

谢谢

最佳答案

关键问题是 Tkinter 和 Twisted 都以相似的方式解决相似的问题,即对外部事件做出异步 react 。 Tkinter 专注于 gui 事件而 Twitsted 专注于 network 事件这一事实只是过去的重要性。

他们所做的具体事情是他们有一个“主循环”结构,一种你失去控制的不归路。在 twisted 的情况下,通常是 reactor.run(),而在 tkinter 中,则是 Tkinter.mainloop()。在程序退出之前,两者都不会返回。

幸运的是,你可以得到 Twisted 到 manage tk's event loop for you!在程序的开头,您应该添加:

from Tkinter import Tk
from twisted.internet import tksupport
root_window = Tk()
tksupport.install(root_window)

然后,一旦你正常创建了你的 gui,你应该调用 Tkinter.mainloop(),使用:

from twisted.internet import reactor
root_window.protocol("WM_DELETE_WINDOW", reactor.stop)
reactor.run()

Tk.protocol() 的奇数位是可选的,但会在 gui 尝试退出时通过正常关闭 react 器来消除一些可怕的异常。


如果这还不够,这里有一些真实的工作代码!首先是一个非常简单的服务器

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

class Echo(Protocol):
def dataReceived(self, data):
print 'recieved:', data
def connectionLost(self, reason):
print 'connection closed', reason

f = Factory()
f.protocol = Echo
reactor.listenTCP(8080, f)
reactor.run()

和一个带有图形用户界面和网络事件的客户端:

from Tkinter import *
from twisted.internet import tksupport, reactor
master = Tk()
tksupport.install(master)

def send_message():
message = e1.get()
reactor.connectTCP("localhost", 8080, MessageCFactory(message))
print("message: %s" % (message))

Label(master, text="Message").grid(row=0)
e1 = Entry(master)
e1.grid(row=0, column=1)
Button(master, text='Send', command=send_message).grid(row=3, column=1, sticky=W, pady=4)

from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet import reactor

class MessageCProto(Protocol):
def connectionMade(self):
self.transport.write(self.factory.message)
self.transport.loseConnection()

class MessageCFactory(ClientFactory):
protocol = MessageCProto

def __init__(self, message):
self.message = message

master.protocol("WM_DELETE_WINDOW", reactor.stop)
reactor.run()

关于python - 运行 reactor.run() 后启动 TCP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25104929/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com