在Python 3中通过LAN发送同步变量文本

在Python 3中通过LAN发送同步变量文本,第1张

在Python 3中通过LAN发送/同步变量/文本

以下是一些文件,可以帮助您为LAN开发消息系统。


Simple_Server.py

#! /usr/bin/env python3import socket, selectdef main():    a = [socket.socket(socket.AF_INET, socket.SOCK_STREAM)]     # socket array    a[0].bind(('', 8989))    a[0].listen(5)    while True:        for b in select.select(a, [], [])[0]:        # ready socket if b is a[0]:     a.append(b.accept()[0]) else:     try:         c = b.recv(1 << 12)   # sent message     except socket.error:         b.shutdown(socket.SHUT_RDWR)         b.close()         a.remove(b)     else:         for d in (d for d in a[1:] if d is not b):  # message sink  d.sendall(c)if __name__ == '__main__':    main()

MultichatClient.py

#! /usr/bin/env python3from safetkinter import *from tkinter.constants import *import socketimport sysclass MultichatClient(frame):    after_handle = None    def __init__(self, master, remote_host):        super().__init__(master)        self.message_area = ScrolledText(self, width=81, height=21,        wrap=WORD, state=DISABLED)        self.message_area.grid(sticky=NSEW, columnspan=2)        self.send_area = Entry(self)        self.send_area.bind('<Return>', self.keyPressed)        self.send_area.grid(sticky=EW)        b = Button(self, text='Send', command=self.mouseClicked)        b.grid(row=1, column=1)        self.send_area.focus_set()        try: self.remote = socket.create_connection((remote_host, 8989))        except socket.gaierror: print('Could not find host {}.'.format(remote_host))        except socket.error: print('Could not connect to host {}.'.format(remote_host))        else: self.remote.setblocking(False) self.after_handle = self.after_idle(self.dataready)        self.grid_rowconfigure(0, weight=1)        self.grid_columnconfigure(0, weight=1)    @classmethod    def main(cls, args):        root = Tk()        root.title('MultichatClient version 1.0')        m = cls(root, args[0])        m.grid(sticky=NSEW)        root.grid_rowconfigure(0, weight=1)        root.grid_columnconfigure(0, weight=1)        root.mainloop()        return 1    def dataready(self):        try: s = self.remote.recv(1 << 12).depre()        except socket.error: pass        else: self.message_area['state'] = NORMAL self.message_area.insert(END, s) self.message_area['state'] = DISABLED self.message_area.see(END)        self.after_handle = self.after(100, self.dataready)    def destroy(self):        if self.after_handle: self.after_cancel(self.after_handle)        super().destroy()    def mouseClicked(self, e=None):        self.remote.sendall(self.send_area.get().enpre() + b'rn')        self.send_area.delete(0, END)    keyPressed = mouseClickedif __name__ == '__main__':    sys.exit(MultichatClient.main(sys.argv[1:]))

Simple_Client.pyw

#! /usr/bin/env python3"""Provide a GUI for easy interactions with Multichat servers.This program is an example of a first attempt at implementing a clientfor interacting with a Multichat server through purely graphical means."""__author__ = 'Stephen "Zero" Chappell <[email protected]>'__date__ = '11 October 2012'__version__ = 1, 0, 0################################################################################from tkinter.messagebox import *from tkinter.constants import *from safetkinter import *import loggingimport tracebackimport _threadimport socketimport osimport tracebackimport sysimport threadbox################################################################################class SimpleClient(frame):    "SimpleClient(master, **kw) -> SimpleClient instance"    @classmethod    def main(cls):        "Create a GUI root and demonstrate the SimpleClient widget."        root = Tk()        root.title('Chat Client')        root.minsize(675, 450)        root.grid_rowconfigure(0, weight=1)        root.grid_columnconfigure(0, weight=1)        root.bind_all('<Control-Key-a>', cls.handle_control_a)        frame = cls(root)        frame.grid(sticky=NSEW)        root.mainloop()    @staticmethod    def handle_control_a(event):        "Process Ctrl-A commands by widget type."        widget = event.widget        if isinstance(widget, Text): widget.tag_add(SEL, 1.0, END + '-1c') return 'break'        if isinstance(widget, Entry): widget.selection_range(0, END) return 'break'    def __init__(self, master, **kw):        "Initialize the SimpleClient instance with the widgets it contains."        super().__init__(master, **kw)        self.grid_rowconfigure(0, weight=1)        self.grid_columnconfigure(0, weight=1)        # Build Widgets        self.output_area = ScrolledText(self, width=25, height=4, wrap=WORD)        self.input_area = Entry(self)        self.corner = Sizegrip(self)        # Place Widgets        self.output_area.grid(row=0, column=0, columnspan=2, sticky=NSEW)        self.input_area.grid(row=1, column=0, sticky=EW)        self.corner.grid(row=1, column=1, sticky=SE)        # Setup Widgets        self.output_area['state'] = DISABLED        self.input_area.bind('<Return>', self.send)        self.after_idle(self.connect)    def connect(self):        "Try connecting to a server to begin chatting."        self.connection = Connector(self, 'Chat Client').connection        if self.connection is None: self._root().destroy()        else: self.connection.setblocking(False) self.after_idle(self.update)    def send(self, event):        "Send a message across the connection from the given widget."        self.connection.sendall(event.widget.get().enpre() + b'rn')        event.widget.delete(0, END)    def update(self):        "Update the output area with any incoming messages."        self.output_area['state'] = NORMAL        try: self.output_area.insert(END, self.connection.recv(1 << 12).depre())        except socket.error: pass        else: self.output_area.see(END)        finally: self.output_area['state'] = DISABLED        self.after(100, self.update)################################################################################def start_thread(function, *args, **kwargs):    "Start a new thread of execution while logging any errors."    _thread.start_new_thread(log_errors, (function, args, kwargs))def log_errors(function, args=(), kwargs={}):    "Execute a function with its arguments and log any exceptions."    try:        function(*args, **kwargs)    except SystemExit:        pass    except:        basename = os.path.basename(sys.argv[0])        filename = os.path.splitext(basename)[0] + '.log'        logging.basicConfig(filename=filename)        logging.error(traceback.format_exc())################################################################################class Dialog(Toplevel): # Copies tkinter.simpledialog.Dialog    "Dialog(parent, title=None) -> Dialog instance"    def __init__(self, parent, title=None):        "Initialize a Dialog window that takes focus away from the parent."        super().__init__(parent)        self.withdraw()        if parent.winfo_viewable(): self.transient(parent)        if title: self.title(title)        self.parent = parent        self.result = None        body = frame(self)        self.initial_focus = self.body(body)        body.grid(sticky=NSEW, padx=5, pady=5)        self.buttonbox()        if not self.initial_focus: self.initial_focus = self        self.protocol('WM_DELETe_WINDOW', self.cancel)        if self.parent is not None: self.geometry('+{}+{}'.format(parent.winfo_rootx() + 50,         parent.winfo_rooty() + 50))        self.deiconify()        self.initial_focus.focus_set()        try: self.wait_visibility()        except tkinter.TclError: pass        else: self.grab_set() self.wait_window(self)    def destroy(self):        "Destruct the Dialog window."        self.initial_focus = None        super().destroy()    def body(self, master):        "Create the body of this Dialog window."        pass    def buttonbox(self):        "Create the standard buttons and Dialog bindings."        box = frame(self)        w = Button(box, text='OK', width=10, command=self.ok, default=ACTIVE)        w.grid(row=0, column=0, padx=5, pady=5)        w = Button(box, text='Cancel', width=10, command=self.cancel)        w.grid(row=0, column=1, padx=5, pady=5)        self.bind('<Return>', self.ok)        self.bind('<Escape>', self.cancel)        box.grid()    def ok(self, event=None):        "Validate and apply the changes made by this Dialog."        if not self.validate(): self.initial_focus.focus_set() return        self.withdraw()        self.update_idletasks()        try: self.apply()        finally: self.cancel()    def cancel(self, event=None):        "Close the Dialong window and return to its parent."        if self.parent is not None: self.parent.focus_set()        self.destroy()    def validate(self):        "Verify that the Dialog is in a valid state."        return True    def apply(self):        "Make any changes the Dialog wishes to accomplish."        pass################################################################################class Connector(Dialog):    "Connector(parent, title=None) -> Connector instance"    def body(self, master):        "Customize the Dialog window with some custom widgets."        self.connection = None        self.resizable(False, False)        # Build Widgets        self.prompt = Label(master, text='Enter server IP address:')        self.address = Entry(master)        # Place Widgets        self.prompt.grid(sticky=W, padx=30, pady=2)        self.address.grid(sticky=W, padx=30)    def buttonbox(self):        "Redefine the buttons at the bottom of the window."        w = Button(self, text='Connect', width=10, command=self.ok,        default=ACTIVE)        w.grid(sticky=E, padx=5, pady=5)        self.bind('<Return>', self.ok)        self.bind('<Escape>', self.cancel)    def validate(self):        "Ask a Consumator to make a connection with the given address."        c = Consumator(self, 'Chat Client', (self.address.get(), 8989))        if c.connection is None: Message(self, icon=WARNING, type=OK, title='Warning',         message='Could not connect to address!').show() return False        self.connection = c.connection        return True################################################################################class Consumator(Dialog):    "Consumator(parent, title, address) -> Consumator instance"    def __init__(self, parent, title, address):        "Initialize the Consumator with the server's address."        self.server_address = address        super().__init__(parent, title)    def body(self, master):        "Create the widgets for this Dialog and start the connection process."        self.connection = None        self.resizable(False, False)        # Build Widgets        self.message = Label(master, text='Trying to connect to address ...')        self.progress = Progressbar(master, orient=HORIZONTAL)        # Place Widgets        self.message.grid(sticky=W, padx=10, pady=2)        self.progress.grid(sticky=EW, padx=10, pady=2)        # Setup Widgets        self.progress.configure(mode='indeterminate', maximum=30)        self.progress.start()        result = []        start_thread(self.connect, result)        self.after_idle(self.poll, result)    def buttonbox(self):        "Cancel the creation of the buttons at the bottom of this Dialog."        pass    @threadbox.metaBox.thread    def connect(self, result):        "Try connecting to the server address that was given."        try: result.append(socket.create_connection(self.server_address, 10))        except socket.timeout: result.append(None)    def poll(self, result):        "Find out if the any connection information is available yet."        if result: self.connection = result[0] self.cancel()        else: self.after(100, self.poll, result)################################################################################if __name__ == '__main__':    log_errors(SimpleClient.main)

亲和力

"""Allow a simple way to ensure execution is confined to one thread.This module defines the Affinity data type that runs pre on a single thread.An instance of the class will execute functions only on the thread that madethe object in the first place. The class is useful in a GUI's main loop."""__author__ = 'Stephen "Zero" Chappell <[email protected]>'__date__ = '4 June 2012'__version__ = 1, 0, 0################################################################################import sysimport _threadimport queue################################################################################def slots(names=''):    "Sets the __slots__ variable in the calling context with private names."    sys._getframe(1).f_locals['__slots__'] =         tuple('__' + name for name in names.replace(',', ' ').split())################################################################################class Affinity:    "Affinity() -> Affinity instance"    slots('thread, action')    def __init__(self):        "Initializes instance with thread identity and job queue."        self.__thread = _thread.get_ident()        self.__action = queue.Queue()    def __call__(self, func, *args, **kwargs):        "Executes function on creating thread and returns result."        if _thread.get_ident() == self.__thread: while not self.__action.empty():     self.__action.get_nowait()() return func(*args, **kwargs)        delegate = _Delegate(func, args, kwargs)        self.__action.put_nowait(delegate)        return delegate.value################################################################################class _Delegate:    "_Delegate(func, args, kwargs) -> _Delegate instance"    slots('func, args, kwargs, mutex, value, error')    def __init__(self, func, args, kwargs):        "Initializes instance from arguments and prepares to run."        self.__func = func        self.__args = args        self.__kwargs = kwargs        self.__mutex = _thread.allocate_lock()        self.__mutex.acquire()    def __call__(self):        "Executes pre with arguments and allows value retrieval."        try: self.__value = self.__func(*self.__args, **self.__kwargs) self.__error = False        except: self.__value = sys.exc_info()[1] self.__error = True        self.__mutex.release()    @property    def value(self):        "Waits for value availability and raises or returns data."        self.__mutex.acquire()        if self.__error: raise self.__value        return self.__value

threadbox.py

"""Provide a way to run instance methods on a single thread.This module allows hierarchical classes to be cloned so that their instancesrun on one thread. Method calls are automatically routed through a specialexecution engine. This is helpful when building thread-safe GUI pre."""__author__ = 'Stephen "Zero" Chappell <[email protected]>'__date__ = '9 October 2012'__version__ = 1, 0, 1################################################################################import functoolsimport affinity################################################################################class _object: __slots__ = '_metaBox__exec', '__dict__'################################################################################class metaBox(type):    "metaBox(name, bases, classdict, old=None) -> metaBox instance"    __REGISTRY = {object: _object}    __SENTINEL = object()    @classmethod    def clone(cls, old, update=()):        "Creates a class preferring thread affinity after update."        classdict = dict(old.__dict__)        classdict.update(update)        return cls(old.__name__, old.__bases__, classdict, old)    @classmethod    def thread(cls, func):        "Marks a function to be completely threaded when running."        func.__thread = cls.__SENTINEL        return func    def __new__(cls, name, bases, classdict, old=None):        "Allocates space for a new class after altering its data."        assert '__new__' not in classdict, '__new__ must not be defined!'        assert '__slots__' not in classdict, '__slots__ must not be defined!'        assert '__module__' in classdict, '__module__ must be defined!'        valid = []        for base in bases: if base in cls.__REGISTRY:     valid.append(cls.__REGISTRY[base]) elif base in cls.__REGISTRY.values():     valid.append(base) else:     valid.append(cls.clone(base))        for key, value in classdict.items(): if callable(value) and (not hasattr(value, '_metaBox__thread') or   value.__thread is not cls.__SENTINEL):     classdict[key] = cls.__wrap(value)        classdict.update({'__new__': cls.__new, '__slots__': (), '__module__':    '{}.{}'.format(__name__, classdict['__module__'])})        cls.__REGISTRY[object() if old is None else old] = new =  super().__new__(cls, name, tuple(valid), classdict)        return new    def __init__(self, name, bases, classdict, old=None):        "Initializes class instance while ignoring the old class."        return super().__init__(name, bases, classdict)    @staticmethod    def __wrap(func):        "Wraps a method so execution runs via an affinity engine."        @functools.wraps(func)        def box(self, *args, **kwargs): return self.__exec(func, self, *args, **kwargs)        return box    @classmethod    def __new(meta, cls, *args, **kwargs):        "Allocates space for instance and finds __exec attribute."        self = object.__new__(cls)        if 'master' in kwargs: self.__exec = kwargs['master'].__exec        else: valid = tuple(meta.__REGISTRY.values()) for value in args:     if isinstance(value, valid):         self.__exec = value.__exec         break else:     self.__exec = affinity.Affinity()        return self

safetkinter.py

"""Register tkinter classes with threadbox for immediate usage.This module clones several classes from the tkinter library for use withthreads. Instances from these new classes should run on whatever threadthe root was created on. Child classes inherit the parent's safety."""__author__ = 'Stephen "Zero" Chappell <[email protected]>'__date__ = '4 June 2012'__version__ = 1, 0, 0################################################################################import timeimport tkinter.filedialogimport tkinter.fontimport tkinter.messageboximport tkinter.scrolledtextimport tkinter.ttkimport threadbox################################################################################tkinter.NoDefaultRoot()@threadbox.metaBox.threaddef mainloop(self):    "Creates a synthetic main loop so that threads can still run."    while True:        try: self.update()        except tkinter.TclError: break        else: time.sleep(tkinter._tkinter.getbusywaitinterval() / 1000)threadbox.metaBox.clone(tkinter.Misc, {'mainloop': mainloop})################################################################################OldButton = threadbox.metaBox.clone(tkinter.Button)Canvas = threadbox.metaBox.clone(tkinter.Canvas)Oldframe = threadbox.metaBox.clone(tkinter.frame)Menu = threadbox.metaBox.clone(tkinter.Menu)PhotoImage = threadbox.metaBox.clone(tkinter.PhotoImage)Spinbox = threadbox.metaBox.clone(tkinter.Spinbox)StringVar = threadbox.metaBox.clone(tkinter.StringVar)Text = threadbox.metaBox.clone(tkinter.Text)Tk = threadbox.metaBox.clone(tkinter.Tk)Toplevel = threadbox.metaBox.clone(tkinter.Toplevel)################################################################################Button = threadbox.metaBox.clone(tkinter.ttk.Button)Checkbutton = threadbox.metaBox.clone(tkinter.ttk.Checkbutton)Entry = threadbox.metaBox.clone(tkinter.ttk.Entry)frame = threadbox.metaBox.clone(tkinter.ttk.frame)Label = threadbox.metaBox.clone(tkinter.ttk.Label)Labelframe = threadbox.metaBox.clone(tkinter.ttk.Labelframe)Progressbar = threadbox.metaBox.clone(tkinter.ttk.Progressbar)Radiobutton = threadbox.metaBox.clone(tkinter.ttk.Radiobutton)Scale = threadbox.metaBox.clone(tkinter.ttk.Scale)Scrollbar = threadbox.metaBox.clone(tkinter.ttk.Scrollbar)Sizegrip = threadbox.metaBox.clone(tkinter.ttk.Sizegrip)Treeview = threadbox.metaBox.clone(tkinter.ttk.Treeview)################################################################################Directory = threadbox.metaBox.clone(tkinter.filedialog.Directory)Font = threadbox.metaBox.clone(tkinter.font.Font)Message = threadbox.metaBox.clone(tkinter.messagebox.Message)ScrolledText = threadbox.metaBox.clone(tkinter.scrolledtext.ScrolledText)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5640251.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存