一天看完python,一天wxpython,马上实践一下。
# -*- coding: utf-8 -*- #Just for fuck jack!!! #----------------------------------- #author philsong [email protected] #V0.0.1 2012-8-14 initial version #V0.0.2 2012-8-15 use mulplex select, wait for notification that an input or output channel is ready #----------------------------------- import wx import socket import thread import sys import select import Queue class chatdlg(wx.Dialog): def __init__(self): wx.Dialog.__init__(self, None, -1, 'chat window', size=(600, 500)) self.DisplayText = wx.TextCtrl(self, -1, '', size=(600, 350), style=wx.TE_MULTILINE) self.InputText = wx.TextCtrl(self, -1, "Hi, jack! What the fuck are u doing now?", pos=(5, 370), size=(500, -1)) self.sendButton = wx.Button(self, -1, "Send", pos=(510, 370)) self.Bind(wx.EVT_BUTTON, self.OnSendClick, self.sendButton) self.sendButton.SetDefault() wx.StaticText(self, -1, "IP", (5, 415)) self.IPText = wx.TextCtrl(self, -1, "219.147.23.114", pos=(30, 415), size=(150, -1)) wx.StaticText(self, -1, "Port", (200, 415)) self.PortText = wx.TextCtrl(self, -1, "8001", pos=(230, 415), size=(50, -1)) self.cButton = wx.Button(self, -1, "Connect as a client", pos=(280, 415)) self.Bind(wx.EVT_BUTTON, self.OnClientClick, self.cButton) self.sButton = wx.Button(self, -1, "Connect as a Server", pos=(390, 415)) self.Bind(wx.EVT_BUTTON, self.OnSeverClick, self.sButton) def OnSendClick(self, event): #self.sendButton.SetLabel("Clicked") self.send_data = self.InputText.GetValue() try: self.client.send(self.send_data) self.DisplayText.AppendText('\nYour said: [') self.DisplayText.AppendText(self.send_data) self.DisplayText.AppendText(']\n') except socket.error, e: self.DisplayText.AppendText('Pls connect to chat server @%d firstly\n' % self.port) def SocketProc_server(self): self.sButton.SetLabel(self.PortText.GetValue()) # Sockets to which we expect to write outputs = [ ] # Outgoing message queues (socket:Queue) message_queues = {} #创建socket并绑定 self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.port = int(self.PortText.GetValue()) self.host = '' print 'Waiting for connection @%s:%d\n' % (self.host, self.port) self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server.bind((self.host, self.port)) self.server.listen(5) self.DisplayText.AppendText('Waiting for connection @%s:%d\n' % (self.host, self.port)) # Sockets from which we expect to read inputs = [ self.server ] while inputs: # Wait for at least one of the sockets to be ready for processing print >>sys.stderr, '\nwaiting for the next event' readable, writable, exceptional = select.select(inputs, outputs, inputs) # Handle inputs for s in readable: if s is self.server: # A "readable" server socket is ready to accept a connection connection, client_address = s.accept() print >>sys.stderr, 'new connection from', client_address self.DisplayText.AppendText('new connection from %s %s\n' % client_address) connection.setblocking(False) inputs.append(connection) # Give the connection a queue for data we want to send message_queues[connection] = Queue.Queue() else: data = s.recv(1024) if data: # A readable client socket has data print >>sys.stderr, 'received [%s] from %s' % (data, s.getpeername()) self.DisplayText.AppendText('received [%s] from %s\n' % (data, s.getpeername())) for c in inputs: if c is self.server: print >>sys.stderr, 'from server' elif c is not s: print >>sys.stderr, 'send_data [%s] to %s' % (data, s.getpeername()) message_queues[c].put('[' + data + '] from'+str(s.getpeername())) if c not in outputs: outputs.append(c) else: # Interpret empty result as closed connection print >>sys.stderr, 'closing', client_address, 'after reading no data' self.DisplayText.AppendText('closing %s %s after reading no data\n\n' % client_address) # Stop listening for input on the connection if s in outputs: outputs.remove(s) inputs.remove(s) s.close() # Remove message queue del message_queues[s] # Handle outputs for s in writable: try: next_msg = message_queues[s].get_nowait() except Queue.Empty: # No messages waiting so stop checking for writability. print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty' outputs.remove(s) else: print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername()) s.send(next_msg) # Handle "exceptional conditions" for s in exceptional: print >>sys.stderr, 'handling exceptional condition for', s.getpeername() self.DisplayText.AppendText('handling exceptional condition for', s.getpeername()) # Stop listening for input on the connection inputs.remove(s) if s in outputs: outputs.remove(s) s.close() # Remove message queue del message_queues[s] def SocketProc_client(self): self.cButton.SetLabel(self.PortText.GetValue()) # Sockets to which we expect to write outputs = [ ] # Outgoing message queues (socket:Queue) message_queues = {} self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.host = str(self.IPText.GetValue()) self.port = int(self.PortText.GetValue()) print 'Connecting to chat server@%s:%d\n' % (self.host, self.port) try: self.client.connect((self.host, self.port)) print 'connected to chat server @%s:%d\n' % (self.host, self.port) self.DisplayText.AppendText('Connected to chat server@%s:%d\n' % (self.host, self.port)) except socket.error, e: print 'Could not connect to chat server @%s:%d\n' % (self.host, self.port) self.DisplayText.AppendText('Could not connect to chat server @%s:%d\n' % (self.host, self.port)) return inputs = [ self.client ] message_queues[self.client] = Queue.Queue() while inputs: # Wait for at least one of the sockets to be ready for processing print >>sys.stderr, '\nwaiting for the next event' readable, writable, exceptional = select.select(inputs, outputs, inputs) # Handle inputs for s in readable: data = s.recv(1024) if data: # A readable client socket has data print >>sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) self.DisplayText.AppendText('received "%s"\n' % data) else: # Interpret empty result as closed connection print >>sys.stderr, 'closing', client_address, 'after reading no data' self.DisplayText.AppendText('closing %s %s after reading no data\n\n' % client_address) # Stop listening for input on the connection if s in outputs: outputs.remove(s) inputs.remove(s) s.close() # Remove message queue del message_queues[s] # Handle outputs for s in writable: try: next_msg = message_queues[s].get_nowait() except Queue.Empty: # No messages waiting so stop checking for writability. print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty' outputs.remove(s) else: print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername()) s.send(next_msg) # Handle "exceptional conditions" for s in exceptional: print >>sys.stderr, 'handling exceptional condition for', s.getpeername() self.DisplayText.AppendText('handling exceptional condition for', s.getpeername()) # Stop listening for input on the connection inputs.remove(s) if s in outputs: outputs.remove(s) s.close() # Remove message queue del message_queues[s] def SocketProc_process(self): pass #recv all recv_data #broadcast msg def OnSeverClick(self, event): self.socketmode=1 thread.start_new_thread(self.SocketProc_server,()) def OnClientClick(self, event): self.socketmode=0 #self.cButton.SetLabel("connected") thread.start_new_thread(self.SocketProc_client,()) if __name__ == '__main__': app = wx.PySimpleApp() app.MainLoop() dialog = chatdlg() result = dialog.ShowModal() if result == wx.ID_OK: print "OK" else: print "Cancel" dialog.Destroy()