-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.py
178 lines (138 loc) · 6.06 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""
client.py
Client side script to be run by every user who wants to connect to
the IRC server and send messages to other connected users.
Author: Meera Murali
Course: CS594 Internetworking Protocols
Date: 12/6/2019
Final Project: A simple IRC application
"""
import socket
import select
import sys
from packet import *
from util import send_packet, print_list, print_dict, ExitIRCApp, ServerCrashError
SERVER_IP_ADDR = "127.0.0.1"
SERVER_PORT = 8080
CLIENT_COMMANDS = {
"create_room": "<room name>",
"join_room": "<room name>",
"leave_room": "<room name>",
"list_rooms": None,
"list_users": "<room name>",
"send_msg": "<room name>:<a message>",
"send_pvt_msg": "<receiver username>:<a message>",
"exit": None
}
def process_packet(packet_json_str):
# convert packet string to JSON
packet = json.loads(packet_json_str)
if packet['opcode'] == 'WELCOME':
print(packet['data'])
elif packet['opcode'] == 'CREATE_ROOM_RES':
print(f"#[{packet['roomname']}] room created!")
elif packet['opcode'] == 'JOIN_ROOM_RES':
print(f"#[{packet['roomname']}] <{packet['username']}> joined the room.")
elif packet['opcode'] == 'LEAVE_ROOM_RES':
print(f"#[{packet['roomname']}] <{packet['username']}> left the room.")
elif packet['opcode'] == 'LIST_USERS_RES':
if len(packet['data']):
print_list(title=f"#{packet['roomname']} users", list_to_print=packet['data'])
else:
print(f"*** No users currently in room {packet['roomname']}! ***")
elif packet['opcode'] == 'LIST_ROOMS_RES':
if len(packet['data']):
print_list(title="Chatrooms", list_to_print=packet['data'])
else:
print("*** No chatrooms created! ***")
elif packet['opcode'] == 'TELL_MSG':
print(f"#[{packet['roomname']}] <{packet['username']}>: {packet['data']}")
elif packet['opcode'] == 'TELL_PVT_MSG':
print(f"#[Private Msg] <{packet['username']}>: {packet['data']}")
elif packet['opcode'] == 'ERROR':
print(f"*** {packet['data']} ***")
elif packet['opcode'] == 'DISCONNECT':
raise ExitIRCApp()
def process_command(command):
command_split = command.replace('\n', '').split(':')
if command_split[0] == "list_rooms":
send_packet(ListRoomsPacket(username=username), server_socket)
elif command_split[0] == "create_room":
if (len(command_split) != 2):
print((
'*** Invalid command! Do you want to create a new chatroom?'
' Try \"create_room:<room name>\". ***'))
else:
send_packet(CreateRoomPacket(username=username, roomname=command_split[1]), server_socket)
elif command_split[0] == "join_room":
if (len(command_split) != 2):
print((
'*** Invalid command! Do you want to join a chatroom?'
' Try \"join_room:<room name>\". ***'))
else:
send_packet(JoinRoomPacket(username=username, roomname=command_split[1]), server_socket)
elif command_split[0] == "leave_room":
if (len(command_split) != 2):
print((
'*** Invalid command! Do you want to leave a chatroom?'
' Try \"leave_room:<room name>\". ***'))
else:
send_packet(LeaveRoomPacket(username=username, roomname=command_split[1]), server_socket)
elif command_split[0] == "list_users":
if (len(command_split) != 2):
print((
'*** Invalid command! Do you want to list users in a chatroom?'
' Try \"list_users:<room name>\". ***'))
else:
send_packet(ListUsersPacket(username=username, roomname=command_split[1]), server_socket)
elif command_split[0] == "send_msg":
if (len(command_split) != 3):
print((
'*** Invalid command! Do you want to send a message?'
' Try \"send_msg:<room name>:<some message>\". ***'))
else:
send_packet(SendMessagePacket(username=username, roomname=command_split[1], msg=command_split[2]), server_socket)
elif command_split[0] == "send_pvt_msg":
if (len(command_split) != 3):
print((
'*** Invalid command! Do you want to send a private message?'
' Try \"send_pvt_msg:<receiver username>:<some message>\". ***'))
else:
send_packet(SendPvtMessagePacket(username=username, receiver=command_split[1], msg=command_split[2]), server_socket)
elif command_split[0] == "exit":
raise ExitIRCApp()
else:
print('*** Invalid command! Here\'s a list of available commands: ***')
print_dict(title="User commands", dict_to_print=CLIENT_COMMANDS)
# Get username from command line arg
if len(sys.argv) != 2:
print ("Correct usage: python3 client.py <username>")
exit()
username = str(sys.argv[1])
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.connect((SERVER_IP_ADDR, SERVER_PORT))
try:
send_packet(RegisterUserPacket(username=username), server_socket)
while True:
# list of possible input streams
sockets_list = [sys.stdin, server_socket]
read_sockets, _, _ = select.select(sockets_list,[],[])
for socket in read_sockets:
# get packet from server
if socket == server_socket:
packet_json_str = socket.recv(2048)
if packet_json_str:
process_packet(packet_json_str)
else:
raise ServerCrashError()
# get command from standard input
else:
command = sys.stdin.readline()
process_command(command)
except ExitIRCApp:
send_packet(ExitPacket(username=username), server_socket)
server_socket.close()
print("Exiting...")
except ServerCrashError:
server_socket.close()
print("Oops! Something went wrong. Connection with server lost. Exiting...")