from wxPython.wx import * import socket,string,sys,thread,select ID_EXIT=101 ID_CONNECT=102 ID_DISCONNECT=103 ID_STARTS=104 ID_INPUT=105 ID_CBUTTON=105 class MySocket(wxFrame): def __init__(self,window): self.window=window self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.peer=None self.is_server=0 def start(self,bind_server=None): """ Start the socket's activity, and set it up to be a server or a client with the optional argument. """ if bind_server: self.is_server=1 try: self.sock.bind(bind_server) except: return 0 self.sock.listen(1) self.keep_running=1 thread.start_new_thread(self.run,()) def stop(self): self.keep_running=0 def run(self): """ If it is a server: If there is no client connected currently, attempt an accept Else, attempt to read from the socket. Else, if the client is connected to a socket, attempt to read """ while self.keep_running: if self.is_server: if not self.peer: i,o,e=select.select([self.sock],[],[],0) if i: conn,addr=self.sock.accept() self.peer=conn,addr self.window.textBox.AppendText('system>> Peer connected from %s:%i.\n'%addr) else: i,o,e=select.select([self.peer[0]],[],[],0) if i: recvd=None recvd=self.peer[0].recv(500) if recvd: self.window.textBox.AppendText('peer>> %s\n'%self.window.rot13(recvd)) else: self.window.textBox.AppendText('system>> Peer closed the socket.\n') self.peer=None elif self.peer: i,o,e=select.select([self.peer[0]],[],[],0) if i: recvd=None recvd=self.peer[0].recv(500) if recvd: self.window.textBox.AppendText('peer>> %s\n'%self.window.rot13(recvd)) else: self.window.textBox.AppendText('system>> Server closed the socket.\n') self.sock=None self.peer=None self.keep_running=0 return class InputFrame(wxMiniFrame): """ The dialog box used by self.get_saddress and self.get_caddress. """ def __init__(self,parent,id,server=0): wxMiniFrame.__init__(self,parent,id,"Configuration", wxDefaultPosition,wxSize(300,170), wxDEFAULT_FRAME_STYLE|wxTINY_CAPTION_HORIZ) self.parent=parent panel=wxPanel(self,-1) iptext=wxStaticText(panel,-1,"IP",wxPoint(50,20)) porttext=wxStaticText(panel,-1,"Port",wxPoint(50,60)) if server: iplist=socket.gethostbyname_ex(socket.gethostname())[2] self.ipfield=wxChoice(panel,-1,wxPoint(100,15),wxSize(100,3),choices=iplist) word='Start' func=self.sbutton else: self.ipfield=wxTextCtrl(panel,-1,"",wxPoint(100,15),wxSize(100,30)) word='Connect' func=self.cbutton self.portfield=wxTextCtrl(panel,-1,"5000",wxPoint(100,55),wxSize(100,30)) button=wxButton(panel,ID_CBUTTON,"%s"%word,wxPoint(100,95)) EVT_BUTTON(panel,ID_CBUTTON,func) self.Show(1) def cbutton(self,event): self.parent.connect((self.ipfield.GetValue(),self.portfield.GetValue())) self.Destroy() def sbutton(self,event): address=self.ipfield.GetStringSelection() if address: self.parent.starts((self.ipfield.GetStringSelection(),self.portfield.GetValue())) self.Destroy() class MyFrame(wxFrame): """ This is the main frame in which input is taken, and data is output. """ def __init__(self,parent,id,title): wxFrame.__init__(self,parent,id,title,wxDefaultPosition, wxSize(410,460),wxMINIMIZE_BOX|wxSYSTEM_MENU| wxCAPTION) self.app=None panel=wxPanel(self,-1) self.CreateStatusBar() menu=wxMenu() menu.Append(ID_CONNECT,"&Connect","Connect to another user.") menu.Append(ID_DISCONNECT,"&Disconnect","Disconnect from the current user.") menu.Append(ID_STARTS,"&Start Server","Start a server.") menu.Append(ID_EXIT,"E&xit","Terminate the program.") menu.GetMenuItems()[1].Enable(0) self.menuBar=wxMenuBar() self.menuBar.Append(menu,"&File") self.SetMenuBar(self.menuBar) #This is the box where the chat-text will go self.textBox=wxTextCtrl(panel,-1,"",wxPoint(0,0), wxSize(400,350),wxTE_MULTILINE|wxTE_READONLY) #This is the box where input will be taken, #encrypted and sent to the other end. self.inputBox=wxTextCtrl(panel,ID_INPUT,"",wxPoint(0,355), wxSize(400,25),wxTE_PROCESS_ENTER) self.sock=None self.input=None EVT_TEXT_ENTER(panel,ID_INPUT,self.send) EVT_MENU(self,ID_CONNECT,self.get_caddress) EVT_MENU(self,ID_DISCONNECT,self.disconnect) EVT_MENU(self,ID_STARTS,self.get_saddress) EVT_MENU(self,ID_EXIT,self.exit) EVT_CLOSE(self,self.exit) def get_caddress(self,event): """ Display a dialog to enter the IP address and the port number of the server to connect to. Send the data to self.connect. """ self.input=InputFrame(self,-1,0) def get_saddress(self,event): """ Display a dialog to select a network device to bind the server to, and to select the port number. Send the data to self.starts. """ self.input=InputFrame(self,-1,1) def connect(self,address): """ Attempt to connect, if it does not, return an error message. """ self.input=None try: address=(address[0],int(address[1])) except: address=None if address: self.sock=MySocket(self) self.sock.start() try: self.sock.sock.connect(address) except: pass if not self.sock.sock.getsockname()[0]=='0.0.0.0': self.sock.peer=(self.sock.sock,address) self.textBox.AppendText('system>> Connected to %s:%i.\n'%address) self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(0) self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(1) self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(0) else: self.disconnect(0) def disconnect(self,event): """ If the socket is active: If the socket is a server, stop the server. Else, disconnect from the server it is connected to. """ if self.sock: self.sock.stop() self.sock=None self.textBox.AppendText('system>> Socket closed.\n') self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(1) self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(0) self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(1) def starts(self,address): """ Attempt to bind to that address, and return an error message if failed. """ self.input=None try: address=(address[0],int(address[1])) except: address=None if address: self.sock=MySocket(self) nok=self.sock.start(address) if not nok: self.textBox.AppendText('system>> Server started.\n') self.textBox.AppendText('system>> Bound to %s:%i.\n'%self.sock.sock.getsockname()) self.menuBar.GetMenu(0).GetMenuItems()[0].Enable(0) self.menuBar.GetMenu(0).GetMenuItems()[1].Enable(1) self.menuBar.GetMenu(0).GetMenuItems()[2].Enable(0) else: self.textBox.AppendText('system>> Server failed to start.\n') def exit(self,event): """ Disconnect and destroy windows! """ self.disconnect(0) self.Destroy() def send(self,event): """ Encrypt the data in the input box with rot13, display it in the local text output box, then send it to the peer. """ data=self.inputBox.GetValue() self.inputBox.Clear() self.textBox.AppendText('local>> %s\n'%data) data=self.rot13(data) if self.sock.peer: self.sock.peer[0].send(data) def rot13(self,data): """ This is certainly no PGP or anything, but I know absolutely nothing about data encryption! It just rotates the alpha characters 13 places. """ case=[] for letter in data: if letter in string.lowercase: case.append(0) else: case.append(1) data=list(data.lower()) for letter in range(len(data)): if data[letter] in string.lowercase: for n in range(13): if string.lowercase.index(data[letter])==25: data[letter]='a' else: data[letter]=string.lowercase[string.lowercase.index(data[letter])+1] for letter in range(len(data)): if data[letter] in string.lowercase: if case[letter]: data[letter]=data[letter].upper() return string.join(data,'') class MyChatApp(wxApp): def OnInit(self): self.frame=MyFrame(None,-1,"Chat") self.frame.app=self self.frame.Show(1) self.SetTopWindow(self.frame) return 1 app=MyChatApp(0) app.MainLoop()