Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#! /usr/bin/env python
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|
# Python P2P Chat Server |
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++|
# First we are importing some libraries which we use in our program
# You can read about each library at https://docs.python.org/3.0/library/index.html
import socket
import sys
import time
import threading
# Now there are two classes (Server and Client)
# One is for listening for messages and second one is for sending the message
# As we are using multithreading in our program. We are creating one thread for listening incoming messages and
# one another thread for sending messages to target.
# /*
# As we are creating threads. we have to specify each thread's activity means ww have to specify what that thread will do.
# There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass
# We are using second method (overriding the run() method in a subclass)
#
# Once a thread object is created, its activity must be started by calling the thread’s start() method. This invokes the run() method in a separate thread of control.
# So it means when we do :
# cli=Client() srv=Server()
# cli.start() OR srv.start()
# We are starting the thread's activity and this will invoke 'def run()' function from each subclass(Server and Client)
# */
# Server
#
# This class is responsible for listening and printing messages on the screen came from client
class Server(threading.Thread): # First we are inheriting a thread class in our server class. This is a class that represents a thread of control.
def run(self):
self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # Create a socket stream
hostname='' # we are not binding our server with any perticular IP
port=51412 # specify the port number on which we want to listen
self.sock.bind((hostname,port)) # Bind that port number with socket
self.sock.listen(1) # Making server listening on given PORT
print "Listening on port %d\n" %port
(clientname,address)=self.sock.accept() # If any client connects with our server or our socket. Accept that connection.
print "Connection from %s\n" % str(address) # Print a message on the screen that this user is connected with us.
# Recieving Messages from the client and output them.
while 1: # A loop which will print the messages came from client side on the screen
chunk=clientname.recv(4096) # Data from client will come in chunk
print str(address)+':'+chunk # Print message on the screen.
# Client
#
# This class is responsible for sending message to server
class Client(threading.Thread):
def connect(self,host,port): # Send a request to the server with host and port taken from the user.
self.sock.connect((host,port)) # Bind socket with server (This will responsible for making connection between server and client)
def client(self,host,port,msg):
sent=self.sock.send(msg) # Send messages to server
def run(self):
self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# Prompting user to enter IP and PORT of the target system.
try:
host=raw_input("Enter the IP :\n>>") # Take IP address of other user
port=int(raw_input("Enter the port :\n>>")) # PORT
except EOFError:
print "Error"
return 1
print "Connecting\n"
s=''
self.connect(host,port) # connect to the host and port given by the user. This fucntion is defined above in this class.
print "Connected\n"
# Taking input and pass it to the client
# Checking for exit condition [ If user typed exit, program will close. ]
while 1: # Infinite loop which will send message to other user Real-Time
msg=raw_input('>>')
if msg=='exit': # If user input `exit` the program will get terminated.
break
if msg=='': # if user input is empty. just continue without doing anything.
continue
self.client(host,port,msg) # Calling client function defined above.
return(1)
# Main
#
# This is our main function. Program execution will start from this line.
if __name__=='__main__': # Executing main function
srv=Server() # Making a thread of Server class
srv.daemon=True # A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised.
srv.start() # Start the activity of this thread.
time.sleep(1) # Put our server to a sleep of 1 Second.
cli=Client() # Making a thread of Client class
cli.start() # Start the activity of this thread.
# Daemon Threads :
# Some threads do background tasks, like sending keepalive packets, or performing periodic garbage collection, or whatever.
# These are only useful when the main program is running, and it's okay to kill them off once the other, non-daemon, threads have exited.
# Without daemon threads, you'd have to keep track of them, and tell them to exit, before your program can completely quit.
# By setting them as daemon threads, you can let them run and forget about them, and when your program quits, any daemon threads are killed automatically.
# if you want to read more about all these things and want to go deep inside this topic.
# Just read :
# https://docs.python.org/3.0/library/socket.html
# https://docs.python.org/3.0/library/sys.html
# https://docs.python.org/3.0/library/time.html
# https://docs.python.org/3.0/library/threading.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment