【问题标题】:How to get input from SocketServer MyTCPHandler to another class如何从 SocketServer MyTCPHandler 获取输入到另一个类
【发布时间】:2013-09-03 21:23:51
【问题描述】:

我正在尝试从 MyTCPHandler 获取输入到以下程序中的类 Network 中。因此,理想情况下,例如,我想从 MyTCPHandler 中获取 self.data 并更改 Network 中的 self._title。像往常一样,我为这个简单的问题道歉,但我对 python 中的类很陌生,我在这个问题上有点挣扎。感谢您的帮助!

from Tkinter import *
import time
import math
import lockfile
import functions
import SocketServer
import threading

class Network(Frame):  
    """ Implements a stop watch frame widget. """                                                               
    def __init__(self, parent=None, **kw):      
        Frame.__init__(self, parent, kw)

        HOST, PORT = "192.168.2.3", 9999
        self._server = SocketServer.TCPServer((HOST, PORT),MyTCPHandler)
        t = threading.Thread(target=self._server.serve_forever)
        t.setDaemon(True) 
        t.start()

        self._title="hello"
        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """

        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()



class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        #I want to set the above title to "self.data"        
        self.request.sendall(self.data.upper())




def main():
    root = Tk()

    #sw = StatusTable(root)
    #sw.pack(side=RIGHT)

    nw = Network(root)
    nw.pack(side=TOP)


    root.mainloop()


if __name__ == '__main__':
    main()

我仍在为此苦苦挣扎,我当前的代码如下。我有两个问题。
1. 理想情况下,我想在 Network 类中设置 IP 地址,这可能吗? 2. self._server 似乎没有属性“_title”,这是我试图从 MyTCPHandler 传递的属性。

from Tkinter import *
import time
import math
import lockfile
import functions
import SocketServer
import threading


class Network(Tk):  
    def __init__(self,server):      
        Tk.__init__(self)

        self._server=server
        t = threading.Thread(target=self._server.serve_forever)
        t.setDaemon(True) # don't hang on exit
        t.start()

        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """

        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()

        radius=20
        l = Label(self,text=self._server._title)
        l.pack(fill=X, expand=NO, pady=2, padx=2)   

class MyTCPHandler(SocketServer.BaseRequestHandler):
    def __init__(self):     
        self._title=StringVar()
        self._title="test"

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        self._title="change"
        print "changed?"
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())



def main():

    HOST, PORT = "10.0.1.08", 9999
    print HOST

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT),MyTCPHandler)

    #sw = StatusTable(root)
    #sw.pack(side=RIGHT)

    nw = Network(server)
    nw.mainloop()

【问题讨论】:

    标签: python sockets tkinter


    【解决方案1】:

    既然两个类都在同一个进程中(因此也是相同的内存空间),为什么不直接使用共享数据呢。如果您担心数据被线程覆盖,那么您可以在该数据上添加锁。

    您还可以考虑使第二个类成为第一个类的实例——在这种情况下,共享数据将是无缝的。这是一个讨论,您可能会觉得有用:How to share data between two classes

    试试这个(可以解除锁定,如果你只有一个客户端并且可以被覆盖):

    lock = threading.Lock()
    data_title = ""
    
    class Network(Tk):
        def __init__(self,server):
            Tk.__init__(self)
    
            self._server=server
            t = threading.Thread(target=self._server.serve_forever)
            t.setDaemon(True) # don't hang on exit
            t.start()
    
            self.makeWidgets()
    
        def makeWidgets(self):
            """ Make the time label. """
            print(dir(self._server))
    
            self._canvas = Canvas(self, width=600, height=400)
            self._canvas.pack()
    
            radius=20
            lock.acquire()
            l = Label(self,text=data_title)
            lock.release()
            l.pack(fill=X, expand=NO, pady=2, padx=2)
    
    class MyTCPHandler(SocketServer.BaseRequestHandler):
        def __init__(self):
            self._title=StringVar()
            self._title="test"
    
        def handle(self):
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            print "{} wrote:".format(self.client_address[0])
            print self.data
            lock.acquire()
            self._title="change"
            lock.release()
            print "changed?"
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())
    

    【讨论】:

    • 这听起来不错。是否有特定的共享数据模块,或者是内置的?
    • 您可以将数据定义为全局变量。如果有多个线程,可以使用 threading 模块提供的锁。
    • 太好了,我去看看。非常感谢。
    • 对于 IP 地址(代码中的 HOST),您应该使用服务器使用的 IP 地址。如果您不知道并且将在服务器上运行此代码,则只需将其保留为空字符串:HOST = ""。
    • 您可以使用 print(dir(self._server)) 打印 self._server 可用的所有方法/属性。如果它没有'_title',那么你不能使用它。为什么要尝试使用不存在的属性?
    猜你喜欢
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多