Saturday 25 June 2016

Simple Python Web Server with CGI

Here is the code for python CGI web server :
 

 CgiServer.py

#!/usr/bin/env python

import BaseHTTPServer
import CGIHTTPServer
import cgitb; cgitb.enable() # This line enables CGI error reporting

ServerHandler = CGIHTTPServer.CGIHTTPRequestHandler
ServerHandler.cgi_directories = ["/"]
HttpServer = BaseHTTPServer.HTTPServer(("", 8000), ServerHandler)
HttpServer.serve_forever()

and here's the code for a sample page:

TestPage.py

#!/usr/bin/env python

print """Content-type:text/html\r\n\r\n
<html>
<head>
 <title>Test Page</title>
</head>
<body>
 <center><h1>Hello world. This is The Test Page</h1></center>
</body>
</html>"""

then set the executable permissions for both file and run the Cgi_Server.py

$ chmod +x CgiServer.py
$ chmod +x TestPage.py
$ ./CgiServer.py

now open your web browser and type the following url

http://localhost:8000/TestPage.py


Voila!! thats it.

for more details visit : https://wiki.python.org/moin/CgiScripts

Wednesday 22 June 2016

Simple Echo Server in python using Sockets

A simple echo server which just echo the client supplied data or string

server.py

#!/usr/bin/python

import socket

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

tcpSocket.bind(("0.0.0.0", 8000))
tcpSocket.listen(2)


while 1:
 print "Waiting for a Client ... "
 (client, (ip, sock)) = tcpSocket.accept()

 print "Received connection from : ", ip
 client.send("Press Return or Ctrl+C to close..\n")
 print "Starting ECHO output ... "

 data = 'dummy'

 while len(data):
  data = client.recv(2048)
  if len(data)==1:
   print "Closing connection with ", ip
   client.close()
   print "Connection closed successfully.!!"
   print "---------------------------------"
   break
  if len(data)==0:
   print "Some Error in connection with ", ip
   print "Connection closed with ", ip
   print "---------------------------------"
   break
  print "Client sent:", data
  client.send(data)

tcpSocket.close()

But the above server code process only a single client at a time.


Now with the use of threading we can solve this problem. Here is the second echo server which handle multiple connection with threads

threaded_server.py

#!/usr/bin/python

import thread
import socket

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

tcpSocket.bind(("0.0.0.0", 8000))
tcpSocket.listen(2)

def conn_handler(client, ip, thread_id):
	print "[T%d]Received connection from : %r" % (thread_id, ip)
	client.send("Press Return or Ctrl+C to close..\n")
	print "[T%d]Starting echo output..." % thread_id
	data = 'dummy'
	while len(data):
		data = client.recv(2048)
		if len(data)==1:
			print "[T%d]Closing connection with %r" % (thread_id, ip)
			client.close()
			print "[T%d]Connection closed successfully.!!" % thread_id
			print "------------------------------------"
			break
		if len(data)==0:
			print "[T%d]Some Error in connection with %r" % (thread_id, ip)
			print "[T%d]Connection closed with %r" % (thread_id, ip)
			print "------------------------------------"
			break
		print "[T%d]Client sent: %s" % (thread_id, data)
		client.send(data)


thread_id = 0
while 1:
	thread_id = thread_id + 1
	print "Waiting for Client ...\n"
	(client, (ip, sock)) = tcpSocket.accept()

	try:
		thread.start_new_thread(conn_handler, (client, ip, thread_id, ))
	except:
		print "Error: Unable to start thread [T%d]\n" % thread_id

tcpSocket.close()


Multi-Process Echo Server 

#!/usr/bin/python

from multiprocessing import Process
import socket
import os
import signal

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

tcpSocket.bind(("0.0.0.0", 8000))
tcpSocket.listen(2)

def conn_handler(client, ip, Child_id):
	print "[C%d]Received connection from : %r" % (Child_id, ip)
	print "[C%d]Starting echo output... " % Child_id
	data = 'dummy'
	while len(data):
		data = client.recv(2048)
		if len(data)==0:
			print "[C%d]Closing connection with %r" % (Child_id, ip)
			client.close()
			print "[C%d]Connection closed with %r" % (Child_id, ip)
			os.kill(os.getpid(), signal.SIGTERM)
		print "[C%d]Client sent: %s" % (Child_id, data)
		client.send(data)

def main():
	Child_id = 0
	while 1:
		Child_id = Child_id + 1
		print "Waiting for Client  ...\n"
		(client, (ip, sock)) = tcpSocket.accept()

		try:
			Process(target=conn_handler, args=(client, ip, Child_id)).start()
		except:
			print "Error: Uable to start Child Process.!![C%d]" % Child_id
	
	tcpSocket.close()


if __name__ == "__main__":
	main()

you can try it out with nc, to close the connection just press 'Ctrl + C' or use the below client.py code to communicate with multiprocess_server.py

client.py

#!/usr/bin/python
import socket
import sys
tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.connect((sys.argv[1], int(sys.argv[2])))
print "Input some string : ['quit' to exit]"
data = "dummy"
while 1:
	data = raw_input("|> ")
	if data=="quit":
		tcpSocket.close()
		break
	tcpSocket.sendall(data)
	result = tcpSocket.recv(2048)
	print result