【问题标题】:Socket Thread and PyGTK套接字线程和 PyGTK
【发布时间】:2010-12-15 18:49:22
【问题描述】:

我正在尝试编写一个即时消息程序,基本的 ui 几乎完成了,我正在研究消息的接收部分。我有一个 UI 类和一个线程化的 Receive_Socket 类。 Received_Socket 类的套接字每次收到消息时,都会执行 gobject.idle_add() 来调用 UI 方法,以便将消息显示到聊天窗口中。在 gobject.idle.add() 行之后,我有一个 while 循环,循环直到消息实际上显示在聊天窗口中(我希望在收到另一条消息之前显示消息,因为我读了那个 gobject.idle_add()不保证执行顺序,当然我希望消息按顺序显示:))

我试着总结一下我的代码:

用户界面类:

Class UI:
##### somewhere in the init #####
    self.message_status = 0
def chat_window(self, contact, message=0):
    Check if a chat window is opened for the contact, if not it opens one.
    => In reality this check if a gtk.Window containing a gtk.Notebook is opened, 
    => if not it opens one
    => Then it creates a page for the contact in the notebook, containing a 
    => gtk.Textview which displays messages
    if message:
        self.message_display(contact, message)
def message_display(self,a,b):
    => Display the message in the message in the contact's textview
    self.message_status = 1

线程 Receive_Socket 类:

Class Receive_Socket(threading.thread):
    message = sock.recv(1024)
    => the sender name is written in the message 
    if message:
        gobject.idle_add(myui.chat_window,sender, message)
        while not myui.message_status:
            time.sleep(0.1)
        myui.message_status = 0

主代码:

if __name__ == "__main__":
    myui = UI()
    reception = Receive_Socket()
    reception.start()
    gtk.main()

我的问题:

1) 这种代码看起来效率高吗?它(与我的 UI 类一起拥有一个线程接收类)是最好的方法吗?

2) 到消息显示的时候,socket 可能已经收到了 2 条或更多条消息,所以当它再次执行 message = sock.recv(1024) 时,多条消息将连接在变量 message 中。我想在每条消息中包含消息长度,因此如果 1024 字节中有超过 1 条消息,它将接收消息并将其余消息放入 message_buffer 变量中,然后在再次执行 sock.recv(1024) 之前检查是否message_buffer 变量包含任何内容,如果是,请将 message_buffer 放入 message 变量中,而不是 sock.recv(1024)。有没有更简单/更好的解决方案来做到这一点?

提前致谢,

诺尔希安

【问题讨论】:

    标签: python sockets pygtk python-multithreading


    【解决方案1】:
    1. 没有。不要使用线程。相反,当套接字准备好读取时,使用glib.io_add_watch 让 gtk/glib 本身调用您的函数。这样你就不会冻结你的 gui 也不需要线程。你也不需要idle_add

    2. 如果你这样做1,你就不会有这个问题,因为消息会按顺序到达,不会有并发线程来混淆数据。

      李>

    【讨论】:

    • 感谢它真的很好用!只是关于 2) 的问题,glib.io_add_watch 是如何工作的?例如,我向套接字发送 3 条消息,当它收到第一个消息时,它调用 glib.io_add_watch 中编写的回调,但是在处理回调时,套接字将接收其他 2 条消息,因此,当回调完成时( return True ),它会看到套接字有数据并再次启动回调,但这一次 fd.recv(1024) 将包含连接的 2 条消息,不是吗?
    • @Nolhian:好吧,当然,您的协议在消息之间肯定有某种分隔符。因此,您必须自己拆分消息,并使用缓冲区来保留部分消息,直到其余消息尚未到达。另一种选择是使用twisted twistedmatrix.com 这是一个网络框架。它的主循环与 gtk 主循环兼容。
    • @nosklo: 可以将glib.io_add_watch 与等待监听的绑定套接字一起使用吗?
    • @hibou57 可以,可以用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 2011-02-11
    • 2013-04-02
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多