用Python和PyGTK编写的聊天程序的问题

时间:2015-04-04 16:36:12

标签: python pygtk chatroom

我是python的新手,我目前正在使用Python进行聊天室程序(仍在进行中......)。我也为我的程序制作了一个GUI。最初,我制作了两个py文件,一个用于GUI,另一个用于聊天功能。他们在分开时都很完美。之后,我合并了两个文件。我遇到了以下两个问题:

  1. 我的一个主题(target = loadMsg)用于等待主持人的消息并在屏幕上打印出来。问题是它每次都会延迟一个msg。例如,我发送了一个" 1"主持人和主持人应该返回一个" 1"立即。但是," 1"我收到的没有出现在我的屏幕上。然后我发送了一个" 2"主持人和主持人应该回复" 2"立即。然后,我的屏幕显示" 1"但是" 2"在主持人回复" 3"在我发送" 3"之后给主人。问题出在哪里?

  2. 这是一个技术问题。我正在测试聊天室的稳定性,我发现大约10%的消息在传输过程中消失了,这种情况随机发生。我该如何解决这个问题?    抱歉我的英语不好。我希望有人可以帮助我.T_T

  3. 以下是我的代码供您参考: ---客户端

    import pygtk,gtk
    import logging
    from threading import *
    import socket
    
    DEBUG = 1
    HOST = ''
    PORT = 8018
    TIMEOUT = 5
    BUF_SIZE = 1024
    
    class Base():
        def reload(self):
            try:
                buf = self.sock.recv(BUF_SIZE)
                print buf
                self.addMsg(buf)
            except:
                pass
        def reload_butt(self,widget):
            try:
                self.thread = Thread(target=self.reload)
                self.thread.start()
            except:
                pass
    
        def loadMsg(self):
            try:
                while True :
                        buf = self.sock.recv(BUF_SIZE)
                    print buf
                    self.addMsg(buf)
                except:
                        self.sock.close()
        def sendMsg(self,widget):
            if DEBUG : print "Send Msg"
            if self.entry.get_text() : self.sock.send(self.entry.get_text())
                self.entry.set_text("")
        def addMsg(self,string):
            if DEBUG : print "Try to add Msg"
            if self.entry.get_text() :
                iter = self.buffer1.get_iter_at_offset(-1)
                self.buffer1.insert(iter,("\n Username: "+string))
                self.entry.set_text("")
                self.adj = self.scrolled_window.get_vadjustment()
                self.adj.set_value( self.adj.upper - self.adj.page_size )
                if DEBUG : print "Add msg ok"
        def destroy(self,widget):
            if DEBUG : print "Destroy function called"
            self.sock.close() 
            gtk.main_quit()
    
        def __init__(self,sock):
            if DEBUG : print "Initializing..."
            self.sock = sock
    
            self.win=gtk.Window()
            self.win.connect("destroy",self.destroy)
    
            self.vbox=gtk.VBox()
            self.win.add(self.vbox)
    
            self.view=gtk.TextView()
            self.view.set_editable(False)
            self.buffer1=self.view.get_buffer()
    
            self.scrolled_window=gtk.ScrolledWindow()
            self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
            self.scrolled_window.add(self.view)
            self.vbox.add(self.scrolled_window)
    
            self.entry=gtk.Entry()
            self.entry.connect("activate",self.sendMsg)
    
            self.enter=gtk.Button("Enter")
            self.enter.connect("clicked",self.sendMsg)
    
            self.reload=gtk.Button("Reload")
            self.reload.connect("clicked",self.reload_butt)
    
            self.hbox=gtk.HBox()
            self.hbox.add(self.entry)
            self.hbox.pack_start(self.reload,False,False)
            self.hbox.pack_start(self.enter,False,False)
            self.vbox.pack_start(self.hbox,False,False)
    
            self.win.show_all()
            if DEBUG : print "Finish initializing"
        def main(self):
            try :
                gtk.main()
            except :
    
                print "Error!!!"
    def main() :
        try :
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
            sock.connect((HOST, PORT)) 
            print ('Connecting to '+ str(HOST) +' ' + str(PORT)) 
            base=Base(sock)
            thread1=Thread(target=base.loadMsg)
            thread2=Thread(target=base.main)
            thread2.start()
            thread1.start()
        except :
            print "Err0r!!!"
            sock.close()
    main()
    

    ---主机(回声主机)

    import socket
    
    HOST = ''
    PORT = 8018
    
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(5)
    
    
    conn, addr = s.accept() 
    print 'Connected by', addr
    try :
        print "Start!"
        while True:
            data = conn.recv(1024)
                print data
            reply = data # echo
            if not reply : break
                if reply== "!q" : 
                        conn.close()
                break   
    
            conn.send(reply)
        conn.close()
    except :
        print "Error!!!!!"
        conn.close()
    

1 个答案:

答案 0 :(得分:0)

我会认真推荐使用gio库(glib的一部分)。使用该库,可以将函数连接到套接字操作,例如数据可用时,或者可以将数据写入套接字。图书馆将在必要时调用这些功能,您不需要等待循环。哪个更适合CPU。

http://jcoppens.com/soft/howto/gtk/chat_socket.php包含一个使用gio的C程序和Python之间的通信示例,这可能对您有用。

这样,您可以在GUI启动后开始监视套接字,并且您不需要线程来参与通信。