1+ #!/usr/bin/python3
12import socket
23import sys
34import threading
45import time
6+ import signal
7+ from cryptography .fernet import Fernet
58i = 0
69class userThread (threading .Thread ):
710 def __init__ (self ,host ,portNumber ,maxUsersCount ):
8- self .host = host
9- self .maxUsersCount = maxUsersCount
10- self .total_user = 0
11- self .connecting_users = []#keep track of connecting users
12- self .portNumber = portNumber
13- self .threads = []#list of socket thread
14- self .users = []#list of usernames of the connected clients
15- self .sock = socket .socket (socket .AF_INET ,socket .SOCK_STREAM )
16- self .sock .bind ((host ,portNumber ))
11+ self .host = host
12+ self .maxUsersCount = maxUsersCount
13+ self .total_user = 0
14+ self .connecting_users = []#keep track of connecting users
15+ self .portNumber = portNumber
16+ self .threads = []#list of socket thread
17+ self .users = []#list of usernames of the connected clients
18+ self .sock = socket .socket (socket .AF_INET ,socket .SOCK_STREAM )
19+ self .sock .bind ((host ,portNumber ))
20+ self .shared_key = b'gWEdcvtXUknmH8li0G_Aj0DrtJPyrg9SP38_zG-0o10='
21+ self .f = Fernet (self .shared_key )
1722 def run (self ):
1823 self .sock .listen (5 )
1924 try :
@@ -22,86 +27,100 @@ def run(self):
2227 #if maximum number of connection reached, send back the #busy status
2328 #to the client and close its connection
2429 if self .total_user == self .maxUsersCount :
25- usrsock .send ("#busy" )
30+ token = self .f .encrypt (b"#busy" )
31+ usrsock .send (token )
2632 usrsock .close ()
2733 else :
28- usrsock .send ("#notbusy" )
34+ token = self .f .encrypt (b"#notbusy" )
35+ usrsock .send (token )
2936 self .threads .append (usrsock )
3037 self .total_user += 1
31- print "Current user count=" ,self .total_user
38+ print ( "Current user count=" ,self .total_user )
3239 threading .Thread (target = self .thread_handler ,args = (usrsock ,)).start ()
33- self .sock .close ()
40+ self .sock .close ()
3441 except socket .error as err :
35- print err
42+ print ( err )
3643 sys .exit ()
37- #handle protocol messages and send broadcast messages
38- def thread_handler (self ,usrsock ):
39- while True :
40- try :
41- resp = usrsock .recv (1024 )#receiving data
42- if resp .startswith ('#join' ):
43- usr = resp .replace ('#join' ,'' ).lstrip ()
44- if usr in self .users :
45- global i
46- usr = usr + str (i )
47- usrsock .send ("#usernametaken %s" % usr )
48- i += 1
49- self .broadcast ("#newuser %s" % usr ,usrsock )
50- self .users .append (usr )
51- usrsock .send ("#welcome %s" % usr )
52- #in order to prevent this thread to send 2 packets at the same time
53- #let it sleep for 1 sec so data can arrive in sequence, not at the same time
54- time .sleep (1 )
55- print "Current connecting users:"
56- for usr in self .users :
57- print usr
58- if len (self .users )> 1 :
59- for i in range (0 ,len (self .users )):
60- usrsock .send ("#prevjoined %s" % self .users [i ])
61- #announce to all the clients that a new user has joined
62- if resp .startswith ('#status' ):
63- usrsock .send ("#statusPosted" )
64- status = resp .replace ('#status' ,'' ).lstrip ()
65- #broadcast status to all other users
66- self .Ibroadcast ("#newStatus %s:%s" % (usr ,status ))
67- if resp .startswith ('#Bye' ):
68- self .broadcast ("#Leave %s" % usr ,usrsock )
69- #broadcast message to all other users saying that a user is leaving
70- usrsock .send ("#Bye" )
71- self .threads .remove (usrsock )#remove that user thread
72- self .total_user -= 1 #subtract 1 from total user
73- self .users .remove (usr )#remove username from list
74- print "Current user count=" ,self .total_user
75- self .usr = "" #set username to empty
76- usrsock .close ()
77- break
78- except IOError as err :
79- print err
80- sys .exit ()
44+
45+ def thread_handler (self ,usrsock ):
46+ while True :
47+ try :
48+ resp = self .f .decrypt (usrsock .recv (1024 )).decode ()#receiving data
49+ if resp .startswith ('#join' ):
50+ usr = resp .replace ('#join' ,'' ).lstrip ()
51+ if usr in self .users :
52+ global i
53+ usr = usr + str (i )
54+ token = self .f .encrypt (("#usernametaken %s" % usr ).encode ())
55+ usrsock .send (token )
56+ i += 1
57+ self .broadcast ("#newuser %s" % usr ,usrsock )
58+ self .users .append (usr )
59+ token = self .f .encrypt (("#welcome %s" % usr ).encode ())
60+ usrsock .send (token )
61+ #in order to prevent this thread to send 2 packets at the same time
62+ #let it sleep for 1 sec so data can arrive in sequence, not at the same time
63+ time .sleep (1 )
64+ print ("Current connecting users:" )
65+ for usr in self .users :
66+ print (usr )
67+ if len (self .users )> 1 :
68+ for i in range (0 ,len (self .users )):
69+ if self .users [i ]!= usr :
70+ token = self .f .encrypt (("#prevjoined %s" % self .users [i ]).encode ())
71+ usrsock .send (token )
72+ #announce to all the clients that a new user has joined
73+ if resp .startswith ('#status' ):
74+ token = self .f .encrypt ("#statusPosted" .encode ())
75+ usrsock .send (token )
76+ status = resp .replace ('#status' ,'' ).lstrip ()
77+ #broadcast status to all other users
78+ self .broadcast ("#newStatus %s:%s" % (usr ,status ),usrsock )#changed from Ibroadcast, work but doesn't look good, lets try gui!
79+ if resp .startswith ('#Bye' ):
80+ self .broadcast ("#Leave %s" % usr ,usrsock )
81+ #broadcast message to all other users saying that a user is leaving
82+ token = self .f .encrypt ("#Bye" .encode ())
83+ usrsock .send (token )
84+ self .threads .remove (usrsock )#remove that user thread
85+ self .total_user -= 1 #subtract 1 from total user
86+ self .users .remove (usr )#remove username from list
87+ print ("Current user count=" ,self .total_user )
88+ self .usr = "" #set username to empty
89+ usrsock .close ()
90+ break
91+ except IOError as err :
92+ print (err )
93+ sys .exit ()
8194#broadcast messages to all clients except the connecting one
82- def broadcast (self ,message ,sock ):
83- for thread in self .threads :
84- if thread != sock :
85- thread .send (message )
86- def Ibroadcast (self ,message ):
87- for thread in self .threads :
88- thread .send (message )
95+ def broadcast (self ,message ,sock ):
96+ for thread in self .threads :
97+ if thread != sock :
98+ token = self .f .encrypt (message .encode ())
99+ thread .send (token )
100+
101+ def Ibroadcast (self ,message ):
102+ for thread in self .threads :
103+ token = self .f .encrypt (message .encode ())
104+ thread .send (token )
89105
106+ # def sig_handler(sig, frame):
107+ # print("Interrupt received, closing program and terminating all connections...")
108+ # sys.exit(1)
90109def main ():
91110 maxUsersCount = 5
92111 portNumber = 58888
93112 if len (sys .argv )< 3 :
94- print "Usage: python Server.py <portNumber> <max user count>"
95- print "Now using port number=" ,portNumber
96- print "Maximum user count=" ,maxUsersCount
113+ print ( "Usage: python Server.py <portNumber> <max user count>" )
114+ print ( "Now using port number=" ,portNumber )
115+ print ( "Maximum user count=" ,maxUsersCount )
97116 else :
98117 portNumber = int (sys .argv [1 ])
99118 maxUsersCount = int (sys .argv [2 ])
100- print "Server now using port number=%d\n Maximum user count=%d" % (portNumber ,maxUsersCount )
119+ print ( "Server now using port number=%d\n Maximum user count=%d" % (portNumber ,maxUsersCount ) )
101120 try :
102121 threads = userThread ('' ,portNumber ,maxUsersCount ).run ()#start the work
103122 except IOError as err :
104- print err
123+ print ( err )
105124 sys .exit ()
106125if __name__ == '__main__' :
107126 main ()
0 commit comments