The script is a PyGtk program which accept calls from a terminal client, the TCP/IP Sockets Client Side script, on the same machine.
- Run the script below and the server will start to listen call from port 5000.
- Run the client script in the same machine, the client will start to connect with the server through port 5000.
- In the client, enter any message and send it to the server.
- See what happens in the server.
- In the client, enter c to close the client connection without closing the server.
- For demonstration purpose, the server can only accept 1 client.
- Non blocking modes and timer triggers are applied on the server side so that the server window can handle other events while waiting for calls.
Source Code
# Title : PyGtk TCP/IP Echo Server - Single Client # Author : Michael Mui # Date : 31/08/2012 # Version : 0.1 # Remark : A TCP/IP server that can accept a single # : client. Messages from the client will be # : printed in the server and echo back to # : the client. import pygtk pygtk.require('2.0') import gtk, pango, gobject import socket # server port number gPort = 5000 class Base: def __init__(self): # define window self.Win = gtk.Window(gtk.WINDOW_TOPLEVEL) self.Win.connect("delete_event", self.WinDelete_event) self.Win.set_title("TCP Server") # Set the border width of the window self.Win.set_border_width(6) self.Win.set_size_request(250,350) # define a vbox self.vbox = gtk.VBox(False, spacing=2) self.vbox.show() # define a label self.lab01 = gtk.Label('Port: '+str(gPort)) self.lab01.show() self.vbox.pack_start(self.lab01,False,False) # define a list self.lstore = gtk.ListStore(gobject.TYPE_STRING) self.listView = gtk.TreeView(self.lstore) # hide the column header of the list self.listView.set_headers_visible(False) mCellRend = gtk.CellRendererText() # text = 0 means get data from [0] of the list store lstore self.tvcol01 = gtk.TreeViewColumn(None,mCellRend, text=0) # attach treeviewcolumn to list self.listView.append_column(self.tvcol01) self.listView.show() # define scroll window to hold the list self.scrollwin = gtk.ScrolledWindow() self.scrollwin.set_policy( gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) self.scrollwin.set_shadow_type(gtk.SHADOW_IN) self.scrollwin.add(self.listView) self.scrollwin.show() self.vbox.pack_start(self.scrollwin,True,True) # define a button self.but01 = gtk.Button("Listen") self.but01.set_size_request(0,40) self.but01.connect("clicked", self.callback, "switchSer") self.but01.show() self.vbox.pack_end(self.but01,False) self.Win.add(self.vbox) self.Win.show() # tcp server self.server_socket = None self.client_socket = None self.runServer = False # Event Handlers # -------------------------------------------------------------- # Delete event def WinDelete_event(self, widget, event, data=None): if self.client_socket<>None: self.client_socket.close() if self.server_socket<>None: self.server_socket.close() gtk.main_quit() return False # internal callback def callback(self, widget, data): if data == 'switchSer': if not self.runServer: self.runServer = True self.but01.set_label("Stop") self.appendMsg('Listening for client...') self.createSerSocket() # start listening to port for every 0.1 sec gobject.timeout_add(100, self.LisTrigger) else: #stop listening to port self.runServer = False self.but01.set_label("Listen") self.appendMsg('Stopped.') self.appendMsg('='*20) if self.server_socket<>None: self.server_socket.close() # create server socket def createSerSocket(self): self.server_socket = socket.socket( \ socket.AF_INET, socket.SOCK_STREAM) self.server_socket.bind(("", gPort)) self.server_socket.setblocking(0) # non-blocking # listener to server socket (run for every 0.1 sec) # looking for new coming client def LisTrigger(self): #print "looking for client..." if self.runServer: try: self.server_socket.listen(1) self.client_socket, maddr = \ self.server_socket.accept() self.appendMsg('Client from %s' % maddr[0]) self.client_socket.setblocking(0) # non-blocking gobject.timeout_add(100, self.LisCliTrigger) return False # stop listening on server socket except: pass return True # keep on listening else: if self.client_socket <> None: self.client_socket.close() return False # stop listening # listener to client socket (run for every 0.1 sec) def LisCliTrigger(self): #print "reading client socket..." try: mdata = self.client_socket.recv(512) if mdata=='c': # close client self.appendMsg('Client is closed.') self.client_socket.close() gobject.timeout_add(100, self.LisTrigger) self.appendMsg('Listening for client...') return False elif mdata == "": self.appendMsg('Client lost connection.') gobject.timeout_add(100, self.LisTrigger) self.appendMsg('Listening for client...') return False elif mdata <> False: self.appendMsg('Client: '+mdata) # echo to client mMsg = "%s\n" % mdata self.client_socket.send(mMsg) except: # client socket waiting... pass return True # append message to the list def appendMsg(self, pMsg): # append to the end of the list self.lstore.append((pMsg,)) # scroll to and select the new message mLast = len(self.lstore) mLast -= 1 self.listView.scroll_to_cell(mLast, None) self.listView.get_selection().select_path(mLast) def main(): gtk.main() if __name__ == "__main__": base = Base() main()
Output
Client Side

Server Side

No comments:
Post a Comment