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