如何不断地从socket python接收请求

时间:2017-05-19 00:18:24

标签: python-3.x sockets user-interface server client

我正在学习python中的套接字,作为练习我用一个文本框,两个输入框和一个按钮制作了一个python gui app。它的工作方式类似于聊天应用程序,我可以同时运行多个模块,并且在每个模块中,当用户输入文本并单击“发送”时,它会在用户模块的文本框中显示输入的消息,并打开所有其他模块。我已经完成了大部分工作,但问题是它只在按下发送按钮时更新文本框但我想不断更新,所以一旦发送新消息,它就会在屏幕上显示。

到目前为止,这是我的代码:

#!/usr/bin/python

class Application(tk.Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.root = tk.Tk()
        self.create_widgets()


    def create_widgets(self):
        ... #code that creates widgets shortended for readability
        #text box widget named self.txt

        self.send_btn["command"] = self.send_msg //this handles sending messages to the server when the button is pressed

        ... #code that creates widgets shortended for readability

    def send_msg(self):
        s = socket.socket()
        host = socket.gethostname()
        port = 9999


        address = (host, port)
        msg=self.name_bar.get() + ": " +self.input_bar.get()
        #name bar is another widget so I can enter an identity for each module
        #input bar is the entry box where text is entered in
        self.input_bar.delete(0, len(msg))

        s.connect(address)
        s.send(msg.encode())

        #Wrote this code that updates textbox when button pushed
        #self.txt.insert(tk.END, s.recv(1024)) 
        #self.txt.insert(tk.END, "\n")

    #Method I created to call constantly to update textbox
    def rcv_msg(self):
        s = socket.socket()
        host = socket.gethostname()
        port = 9999

        address = (host, port)

        s.connect(address)

        if s.recv(1024).decode() != "":
            #self.txt.insert(tk.END, s.recv(1024)) 
            #self.txt.insert(tk.END, "\n")

我最近也在做Java,所以如果我的术语混淆了,我会道歉。 我已经制作了更新文本框的方法,我只是不知道如何调用它,我尝试了一个while循环,但它只是阻止应用程序运行。此外,服务器非常简单,只需将客户端上面的消息发送到客户端打开的所有模块。我不知道代码是否必要,我之前被告知要尽量保持问题简短,但如果需要,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:1)

你可以听一些新信息。一个不会干扰GUI的独立线程。 (伪代码!)

import socket
from threading import Thread, Lock
import time

class ListenThread(Thread):

    def __init__(self, app, lock):
        Thread.__init__(self)
        self._app = app
        self._lock = lock
        self._terminating = False

    def destroy(self):
        self._terminating = True

    def run(self):
        s = socket.socket()
        host = socket.gethostname()
        port = 9999
        address = (host, port)

        while True:

            if self._terminating:
                break;

            if s.recv(1024).decode() != "":
                self._lock.acquire()
                self._app.post_new_data(s.recv(1024))
                self._lock.release()
            time.sleep(0.1)

class App(object):

    # ...

    def __init__(self):
        self._lock = Lock()
        self._listener = ListenThread(self, self._lock)
        self._listener.start()

    def post_new_data(self, data):

        # Post information to the GUI

    def all_data(self):
        self._lock.acquire()
        # ...
        self._lock.release()

    def destroy(self):
        self._listener.destroy()


# ... Tk mainloop ...

击穿

class ListenThread(Thread):

此项目将侦听来自其他连接的新数据,并通过self._app.post_new_data(...)操作中的run(self)调用将其发布到GUI。

    def run(self):
        s = socket.socket()

当我们第一次开始在一个线程上执行时(通过start()),我们创建了socket并获得连接。这样,所有传入的传输都将通过此路由,以保持我们的GUI免费用于它喜欢做的事情(绘制界面,接受用户输入等)。

while上的ListenThread.run循环将继续查找新数据,直到我们杀死该帖子为止。一旦收到数据,它就会将该信息推送到我们的App。在post_new_data函数中,您可以将新数据添加到GUI,存储它,无论您想要什么。

    def post_new_data(self, data):
        self.txt.insert(tk.END, data)
        self.txt.insert(tk.END, "\n")