Skip to content

Commit 70c4dd8

Browse files
authored
Add files via upload
1 parent a8c51ed commit 70c4dd8

2 files changed

Lines changed: 189 additions & 0 deletions

File tree

Python Chatroom/Client.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#Nathan Jones - 19696498
2+
#Advanced Programming Additional Feature
3+
#2023
4+
5+
from colorama import init #IMPORTING 'colorama' FEATURE THAT ALLOWS THE PROGRAM TO GIVE DIFFERENT COLOURS TO THE USERS
6+
from colorama import Fore, Back, Style #IMPORTING 'colorama' FEATURE THAT ALLOWS THE PROGRAM TO GIVE DIFFERENT COLOURS TO THE USERS
7+
8+
import socket #ALLOWS FOR THE PROGRAM TO GATHER IP AND MAC ADDRESSES AND CONNECTIVITY TO IP SERVERS THROUGH PORTS
9+
import threading #ALLOWING THE PROGRAM TO RUN ON MULTIPLE THREADS
10+
import sys #ALLOWS ACCESS TO THE SYSTEM FROM WITHIN PYTHON
11+
import datetime #THIS ALLOWS FOR THE CURRENT TIME TO BE IMPORTED AND DISPLAYED FOR THE USER TO SEE
12+
13+
init()
14+
Colour = '6'
15+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #ALLOWS GRAND CENTRAL TO GATHER THE CURRENT IP ADDRESS
16+
port = 1234 #DEFINING THE PORT TO BE USED TO SEND AND RECIEVE DATA/MESSAGES
17+
18+
print('Welcome To The CMP9133 Advanced Programming Curling Messenger Server'+'\n')
19+
Uname = input('Enter Online Name:: ')
20+
Colour = input('''
21+
Colour Selection
22+
1. Red 5. Cyan
23+
2. Blue 6. White
24+
3. Green 7. Magenta
25+
4. Yellow
26+
27+
Option:
28+
''')
29+
if Colour == '1':
30+
uname = Style.BRIGHT +Fore.RED + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
31+
elif Colour == '2':
32+
uname = Style.BRIGHT +Fore.BLUE + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
33+
elif Colour == '3':
34+
uname = Style.BRIGHT +Fore.GREEN + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
35+
elif Colour == '4':
36+
uname = Style.BRIGHT +Fore.YELLOW + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
37+
elif Colour == '5':
38+
uname = Style.BRIGHT +Fore.CYAN + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
39+
elif Colour == '6':
40+
uname = Style.BRIGHT +Fore.WHITE + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
41+
elif Colour == '7':
42+
uname = Style.BRIGHT +Fore.MAGENTA + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
43+
else:
44+
uname = Style.BRIGHT +Fore.WHITE + Uname + Style.RESET_ALL #CREATING THE USERNAME FOR THIS ACCOUNT AND THEN ASSIGNING A COLOUR TO THE USERNAME
45+
46+
47+
ip = input('Enter the IP Address:: ') #USER ENTERS THE IP OF THE GRAND CENTRAL CHATROOM SERVER THAT WILL ALWAYS STAY THE SAME UNLESS CONNECTING TO ANOTHER SERVER
48+
49+
s.connect((ip, port)) #CONNECTING TO THE IP ADDRESS THAT WAS ENTERED ABOVE THROUGH THE PORT THAT WAS DEFINED
50+
s.send(uname.encode('ascii')) #AFTER IT HAS CONNECTED TO THE SERVER THE USERNAME OF THIS CLIENT WILL BE SENT TO THE SERVER
51+
52+
clientRunning = True #SETTING THE 'clientRunning' TO TRUE SO THE PROGRAM KNOWS IT HAS ATTEMPTED TO MAKE A HANDSHAKE WITH THE SERVER
53+
54+
def receiveMsg(sock):
55+
Colour
56+
serverDown = False #SETTING THE 'serverDown' VARAIBLE TO BE FALSE SO THAT THE PROGRAM KNOWS IT HAS RECIEVED A RESPONSE FROM THE SERVER
57+
while clientRunning and (not serverDown): #THE WHILE LOOP WILL ONLY BE IN AFFECT WHILST THE 'clientRunning' VARIABLE IS SET TO TRUE
58+
try:
59+
msg = sock.recv(1024).decode('ascii') #RECIVING THE WELCOME MESSAGE FROM THE SERVER AND DECODING IT FROM ASCII
60+
print(msg)
61+
except:
62+
print('Server is ' + Style.BRIGHT +Fore.RED + str('Down') + Style.RESET_ALL + '. You are now Disconnected. Press enter to exit...') #NO MESSAGE FROM THE SERVER THEN THE PROGRAM WILL DISPLAY A MESSAGE SAYING SERVER DOWN
63+
serverDown = True #CHANGING THE 'serverDown' VARIABLE TO BE TRUE
64+
65+
threading.Thread(target = receiveMsg, args = (s,)).start() #TELLING THE PROGRAM WHAT THREADS TO RUN AT THE SAME TIME
66+
while clientRunning:
67+
68+
time = datetime.datetime.now() #DEFINING A SHORTER NAME FOR THE FUNCTION THAT DISPALAYS THE CURRENT TIME
69+
MSG = input() #DEFINING WHAT THE USER INPUTS AS THE MESSAGE THAT WILL BE SENT
70+
if Colour == '1':
71+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
72+
elif Colour == '2':
73+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
74+
elif Colour == '3':
75+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
76+
elif Colour == '4':
77+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
78+
elif Colour == '5':
79+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
80+
elif Colour == '7':
81+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
82+
elif Colour == '8':
83+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
84+
else:
85+
msg = str(time.strftime("%H:%M ")) + '<' + Style.BRIGHT +Fore.RED + str(uname) + Style.RESET_ALL + '> ' + MSG #ADDING THE MESSAGE TO THE TIME STAMP + USERNAME SO USERS KNOW WHO SENT IT
86+
87+
88+
if '@quit' in msg: #IF THE MESSAGE CONTAINS '@quit' THEN THE FOLLOWING WOULD TAKE PLACE
89+
clientRunning = False #CHANGING THE 'clientRunning' VARIABLE TO BE FALSE
90+
s.send('@quit'.encode('ascii')) #SENDING THE '@quit' MESSAGE TO THE SEVER THAT WILL DISCONNECT THE USER FROM THE SERVER
91+
else:
92+
s.send(msg.encode('ascii')) #IF IT DOES NOT CONTAIN '@quit' IT WILL SEND TEH MESSAGE TO THE SERVER THAT WILL THEN DISTRIBUTE THE MESSAGE
93+
94+
#Nathan Jones - 19696498 - 2023

Python Chatroom/Server.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#Nathan Jones - 19696498
2+
#Advanced Programming Additional Feature
3+
#2023
4+
5+
from colorama import init #IMPORTING 'colorama' FEATURE THAT ALLOWS THE PROGRAM TO GIVE DIFFERENT COLOURS TO THE USERS
6+
from colorama import Fore, Back, Style #IMPORTING 'colorama' FEATURE THAT ALLOWS THE PROGRAM TO GIVE DIFFERENT COLOURS TO THE USERS
7+
8+
import socket #ALLOWS FOR THE PROGRAM TO GATHER IP AND MAC ADDRESSES AND CONNECTIVITY TO IP SERVERS THROUGH PORTS
9+
import threading #ALLOWING THE PROGRAM TO RUN ON MULTIPLE THREADS
10+
import datetime #THIS ALLOWS FOR THE CURRENT DATE/TIME TO BE IMPORTED AND DISPLAYED FOR THE USER TO SEE
11+
12+
init()
13+
14+
date = datetime.date.today() #DEFINING A SHORTER NAME FOR THE FUNCTION THAT DISPALAYS THE CURRENT TIME
15+
time = datetime.datetime.now() #DEFINING A SHORTER NAME FOR THE FUNCTION THAT DISPALAYS THE CURRENT DATE
16+
17+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #ALLOWS GRAND CENTRAL TO GATHER THE CURRENT IP ADDRESS
18+
serverRunning = True #SETTING THE 'serverRunning' TO TRUE SO THE PROGRAM KNOWS THE SERVER HAS STARTED
19+
ip = str(socket.gethostbyname(socket.gethostname())) #ALLOWS GRAND CENTRAL TO GATHER THE CURRENT IP ADDRESS OF THE SYSTEM
20+
port = 1234 #DEFINING THE PORT TO BE USED TO SEND AND RECIEVE DATA/MESSAGES
21+
22+
clients = {} #CREATING THE DICTIONARY THAT WILL STORE ALL OF THE USERS CHATROOM CLIENT THAT CONNECT TO THE SERVER
23+
24+
s.bind((ip, port)) #ASSIGNING THE PORT AND IP ADDRESS OF THE SERVER
25+
s.listen() #LISTENING FOR THE OTHER CLIENTS TO CONNECT
26+
27+
print(('CMP9133 Advanced Programming Curling Messenger Server')+Style.BRIGHT+Fore.GREEN+str(' ONLINE')+Style.RESET_ALL+str('...')) #SHOWING THAT THE SERVER IS ON
28+
#THE LINE BELOW DISPLAYS WHEN THE SERVER WAS STARTED BY GIVING THE DATE AND TIME, WITH 'ONLINE' AND THE TIME AND DATE BEING DISPLAYED IN GREEN
29+
print(('Server')+Style.BRIGHT+Fore.GREEN+str(' ONLINE')+Style.RESET_ALL+str(' since: ')+Style.BRIGHT+Fore.GREEN+str(date.strftime("%d|%m|%Y "))+Style.RESET_ALL+str('@ ')+Style.BRIGHT+Fore.GREEN+str(time.strftime("%H:%M "))+ Style.RESET_ALL)
30+
print('Ip Address of the Server:: '+ Style.BRIGHT + Fore.BLUE + str(ip) + Style.RESET_ALL) #DISPLAYING THE SERVER'S IP ADDRESS TO CONNECT TO AND CHANGING THE IP ADDRESS COLOUR TO BLUE
31+
32+
def handleClient(client, uname):
33+
clientConnected = True #CREATING A VARIABLE THAT WILL BE TRUE IF OTHER USERS HAVE CONNECTED
34+
keys = clients.keys() #CREATING A VARIABLE THAT WILL STORE THE USERS CHATROOM CLIENTS AS KEYS, SO THEY CAN BE IDENTIFED
35+
help = ('''
36+
37+
There Are 4 Commands In Messenger:
38+
39+
@online = Shows All The People Currently Online
40+
@disconnect = Ends Your session And Disconnects
41+
@all = Sends The Message To Everyone On The Server
42+
@'Username' = Sends The Message To Particular User
43+
44+
''') #CREATING THE HELP MENU THAT WILL BE DISPLAYED WITHIN THE CLIENTS OF THE USERS THAT HAVE CONNECTED AND WILL TELL THEM THE BASIC COMMANDS
45+
46+
while clientConnected: #WHILST THE USERS CHATROOM CLIENTS ARE CONNECTED THEN THE FOLLOWING WILL TAKE PLACE
47+
time = datetime.datetime.now() #DEFINING A SHORTER NAME FOR THE DATE TIME MODULE SO IT CAN BE CALLED LATER ON
48+
try:
49+
msg = client.recv(1024).decode('ascii') #DECODING THE MESSAGES THAT THE SERVER RECIEVES FROM THE CHATRROM CLIENTS
50+
response = (('Number of People')+Style.BRIGHT +Fore.GREEN + str(' ONLINE') + Style.RESET_ALL+'\n') #DISPLAYING THE TITLE FOR THE NUMBER OF CHATROOM CLIENTS THAT HAVE CONNECTED
51+
found = False
52+
if '@online' in msg: #IF A CHATROOM CLIENT MESSAGE CONTAINS '@online' THEN THE FOLLOWING WILL TAKE PLACE
53+
clientNo = 0 #DEFINING HOW MANY CHATROOM CLIENTS ARE ONLINE
54+
for name in keys: #IF THERE ARE CHATROOM CLIENTS THAT HAVE CONNECTED AND ARE STORE IN THE KEYS THE FOLLOWING WILL TAKE PLACE
55+
clientNo += 1 #ADDING TO THE NUMBER OF USERS CONNECTED TO KEEP A COUNT OF PEOPLE
56+
response = response + str(clientNo) +'::' + name+'\n' #CREATING A RESPONSE TO DISPLAY HOW MANY USERS ARE CONNECTED FOLLOWED THE NAMES OF THE USERS
57+
client.send(response.encode('ascii')) #SENDING THE RESPONSE TO THE USERS CLIENT AND ENCODING TEH MESSAGE BEFORE IT IS SENT
58+
elif '@help' in msg: #IF A CHATROOM CLIENT MESSAGE CONTAINS '@help' THEN THE FOLLOWING WILL TAKE PLACE
59+
client.send(help.encode('ascii')) #SENDS THE USERS CLIENT THE HELP MESSAGE THAT DISPLAYS ALL OF THE COMMANDS FOR THE CHATROOM
60+
elif '@all' in msg: #IF A CHATROOM CLIENT MESSAGE CONTAINS '@all' THEN THE FOLLOWING WILL TAKE PLACE
61+
msg = msg.replace('@all','') #THE MESSAGE THAT HAS BEEN SENT WILL REPLACE THE '@all' WITH NOTHING
62+
for k,v in clients.items():
63+
v.send(msg.encode('ascii')) #SENDING THE MESSAGE TO ALL USERS IN THE CHATROOM AT THAT TIME AND IN THE PROCESS WILL ENCODE THE MESSAGE
64+
elif '@disconnect' in msg: #IF A CHATROOM CLIENT MESSAGE CONTAINS '@disconnect' THEN THE FOLLOWING WILL TAKE PLACE
65+
response = Style.BRIGHT +Fore.RED + str('ENDING') + Style.RESET_ALL + ' Session and exiting...' #CREATING A RESPONSE TO DISPLAY THATV THEIR SESSION IS ENDING/DISCONNECTING
66+
client.send(response.encode('ascii'))#SENDING THAT RESPONSE TO THE SPECIFIC USERS CLIENT AND ENCODING IT BEFORE SENDING
67+
clients.pop(uname) #PHYSICALLY REMOVING THE USERS CLIENT FROM THE SERVER
68+
response1 = uname + Style.BRIGHT +Fore.RED + str('LOGGED OUT') + Style.RESET_ALL
69+
client.send(response.encode('ascii'))#SENDING THAT RESPONSE TO THE SPECIFIC USERS CLIENT AND ENCODING IT BEFORE SENDING
70+
print(uname + ' has logged out') #DISPLAYING IN THE SERVER WINDOW THAT THE USER HAS LOGGED OUT
71+
clientConnected = False #CHANGING THE VARIABLE THAT STATES IF A USER IS STILL CONNECTED
72+
else:
73+
for uname in keys:
74+
if('@'+uname) in msg: #IF A MESSAGE WITHIN THE CHATROOM CONTAINS A NAME OF ONE OF THE USERS IT WILL SEND IT TO THAT USER
75+
msg = msg.replace('@'+uname, ''+str(time.strftime("%H:%M "))) #ADDING THE TIME TO THE MESSAGE AND ADDING THE USER THE MESSAGE IS GOING TO
76+
clients.get(uname).send(msg.encode('ascii')) #ENCODING THE MESSAGE AND GATHER THE INFORMATION WHERE TO SEND THE MESSAGE
77+
found = True #IF THE USER THAT THE MESSAGE IS BEING SENT TO HAS BEEN FOUND THEN THE VARIABLE IS SET TO 'True'
78+
if(not found):
79+
client.send('Trying to send message to invalid person.'.encode('ascii')) #IF THE USER CANNOT BE FOUND THEN THIS MESSAGE WILL BE SENT TO THE USER WHO SENT THE MESSAGE
80+
except:
81+
clients.pop(uname) #SEEING IF THE USER TEHY ARE TRYING TO SEND THE MESSAGE TO HAS LOGGED OUT
82+
print(uname + ' has Disconnected') #DISPLAYING A MESSAGE SAYING THAT THE USER THEY TRIED TO SEND THE MESSAGE TO HAS LOGGED OUT
83+
clientConnected = False #CHANGING THE VARIABLE TO 'False' THAT STATES WHETHER THE USER'S CLIENT HAS CONNECTED
84+
85+
while serverRunning: #THIS LOOP ONLY RUNS WHILST THE 'serverRunning' VARIABLE IS TRUE
86+
client, address = s.accept() #ACCEPTING THE REQUESTS FROM THE USER'S CLIENTS THAT ARE TRYING TO CONNECT WITH THE SERVER
87+
uname = client.recv(1024).decode('ascii') #RECIEVING THE USER'S CHATROOM CLIENTS USERNAME SO IT CAN BE DISPLAYED
88+
print('%s connected to the server'%str(uname)) #DISPLAYING WITHIN THE SERVER WINDOW THAT A NEW USER HAS CONNECED ALONG WITH THEIR USERNAME
89+
client.send('You are ONLINE Type @help to know all the commands'.encode('ascii')) #SENING THE WELCOME MESSAGE TO THE USER'S CLIENT
90+
91+
if(client not in clients): #IF THE CLIENTS USERNAME IS NOT IN THE SYSTEM THE FOLLOWING WILLN TAKE PLACE
92+
clients[uname] = client #ADDING THE CLIENTS CHATROOM USERNAME TO THE DICTIONARY
93+
threading.Thread(target = handleClient, args = (client, uname, )).start() #STARTING ANOTHER THREAD FOR THAT USER SO THEY CAN HAVE ACCESS TO THE SERVER AND SEND MESSAGES
94+
95+
#Nathan Jones - 19696498 - 2023

0 commit comments

Comments
 (0)