Created
February 20, 2014 07:16
-
-
Save eeddaann/9108492 to your computer and use it in GitHub Desktop.
our project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dos |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<module type="PYTHON_MODULE" version="4"> | |
<component name="NewModuleRootManager"> | |
<content url="file://$MODULE_DIR$" /> | |
<orderEntry type="inheritedJdk" /> | |
<orderEntry type="sourceFolder" forTests="false" /> | |
</component> | |
<component name="PyDocumentationSettings"> | |
<option name="myDocStringFormat" value="Plain" /> | |
</component> | |
<component name="TestRunnerService"> | |
<option name="projectConfiguration" value="Unittests" /> | |
<option name="PROJECT_TEST_RUNNER" value="Unittests" /> | |
</component> | |
</module> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectRootManager" version="2" project-jdk-name="Python 2.7.5 (G:/Python27/python.exe)" project-jdk-type="Python SDK" /> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/.idea/dos.iml" filepath="$PROJECT_DIR$/.idea/dos.iml" /> | |
</modules> | |
</component> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<component name="DependencyValidationManager"> | |
<state> | |
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> | |
</state> | |
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="VcsDirectoryMappings"> | |
<mapping directory="" vcs="" /> | |
</component> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The COMPLETED solution of Stav and Ofir - CLIENT (1-13) | |
# Imports | |
import socket | |
import sys | |
import select | |
import struct | |
import cPickle | |
import msvcrt | |
marshall = cPickle.dumps | |
unmarshall = cPickle.loads | |
# Constants | |
SERVER = '127.0.0.1' # TODO: Change this | |
PORT = 33440 | |
TIMEOUT = 0.1 # Timeout, in seconds, for select command | |
# Commands | |
COMMAND_SIZE = struct.calcsize("L") | |
SEND_MESSAGE_COMMAND = 1 # The command that represents sending a message] | |
KICK_USER_COMMAND = 2 | |
DECLARE_USER_NAME = 3 | |
ADD_ADMIN_COMMAND = 4 | |
VIEW_MANAGERS = 5 | |
MUTE_USER_COMMAND = 6 | |
PRIVATE_MSG_COMMAND = 7 | |
def send_size_and_argument(active_socket, argument): | |
'''Helper function used to send the length of an argument and then the argument itself. For example: 5, hello. | |
Receives: active_socket - the socket on which the parameters should be sent. | |
argument - the argument to send as a string. For example - hello. | |
Returns: nothing.''' | |
# Get the size to send it first | |
value = socket.htonl(len(argument)) | |
# Pack it | |
size = struct.pack("L",value) | |
# Send the size | |
active_socket.send(size) | |
# Send the argument | |
active_socket.send(argument) | |
def send_command(active_socket, command): | |
'''Helper function used to send a command. | |
Receives: active_socket - the socket on which the parameters should be sent. | |
command - the command to send. | |
Returns: nothing.''' | |
value = socket.htonl(command) | |
send_command = struct.pack("L", value) | |
active_socket.send(send_command) | |
def send_chat_message(active_socket, user_name, message): | |
'''Sends the chat message to the server using the fomrat of: | |
<user_name_length><user_name><SEND_MESSAGE_COMMAND><message_length><message> | |
Receives: | |
active_socket - the socket of connection with the server. | |
user_name - the user name of the writer. | |
message - the chat message to send. | |
Returns: nothing.''' | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, SEND_MESSAGE_COMMAND) | |
send_size_and_argument(active_socket, message) | |
def kick_user_from_chat(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, KICK_USER_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def declare_user_name(active_socket,user_name): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, DECLARE_USER_NAME) | |
send_size_and_argument(active_socket, user_name) | |
def add_admin(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, ADD_ADMIN_COMMAND) | |
message = message[4:] | |
send_size_and_argument(active_socket, message) | |
def view_managers(active_socket,user_name): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, VIEW_MANAGERS) | |
def mute_user(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, MUTE_USER_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def send_private_msg(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, PRIVATE_MSG_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def receive_from_server(active_socket): | |
'''Function used to receive data from the server. | |
Receives: active_socket - the socket with the server. | |
Returns: data retrieved from the socket. | |
In case of an error - returns an empty string.''' | |
# Get the size of the data from the server | |
size_of_size = struct.calcsize("L") | |
size = active_socket.recv(size_of_size) | |
try: | |
# Try to parse the size of the given message. | |
size = socket.ntohl(struct.unpack("L", size)[0]) | |
except struct.error, e: | |
# In case of an error, return an empty string. | |
return '' | |
buf = "" | |
# Attempt to receive the whole message! | |
while len(buf) < size: | |
buf = active_socket.recv(size - len(buf)) | |
return unmarshall(buf)[0] | |
# Create the main socket - connection with the server | |
try: | |
# Create a TCP socket | |
# AF_INET means IPv4. | |
# SOCK_STREAM means a TCP connection. | |
# SOCK_DGRAM would mean an UDP "connection". | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
# Connect to the server | |
sock.connect((SERVER, PORT)) | |
print 'Connected to the server!' | |
# Grab user name from the user... | |
user_name = raw_input('Please choose a user name --> ') | |
declare_user_name(sock,user_name) | |
except socket.error, e: | |
# An error occurred | |
print 'Error connecting to server!' | |
# Quit | |
sys.exit(1) | |
# Run this loop forever... | |
input_from_user= '' | |
while True: | |
try: | |
# Wait for input from the server socket | |
rlist, wlist, xlist = select.select( [sock], [], [], TIMEOUT) | |
for current_socket in rlist: | |
# We have a message from the server! | |
data = receive_from_server(sock) | |
if data == "": | |
# We failed to receive data. The connection terminated. | |
print 'Shutting down.' | |
sys.exit(1) | |
else: | |
# We received the data successfully! Write it to the user! | |
print data | |
# Try to read from the user | |
# Note that this code is non blocking, so a read operation on the socket | |
# is also possible | |
# If any key was pressed | |
if msvcrt.kbhit(): | |
# Save the key that was pressed | |
keypressed = msvcrt.getch() | |
# Present the key on the screen for the user to see | |
sys.stdout.write(keypressed) | |
# if the key that was pressed was <Enter>: | |
if keypressed == '\r' or keypressed == '\n': | |
sys.stdout.write('\n') | |
# input_from_user is ready, so we can use it! | |
# We want to send the message to the server... | |
if 'KICK ' in input_from_user: | |
kick_user_from_chat(sock, user_name, input_from_user) | |
elif 'ADD ' in input_from_user: | |
add_admin(sock, user_name, input_from_user) | |
elif 'view-managers' == input_from_user: | |
view_managers(sock, user_name) | |
elif 'MUTE ' in input_from_user: | |
mute_user(sock, user_name, input_from_user) | |
elif 'SEND ' in input_from_user: | |
send_private_msg(sock, user_name, input_from_user) | |
else: | |
send_chat_message(sock, user_name, input_from_user) | |
# Initialize input_from_user | |
input_from_user = '' | |
else: | |
# input_from_user is not ready, so concate the pressed key | |
input_from_user += keypressed | |
except KeyboardInterrupt: | |
print 'Interrupted.' | |
sock.close() | |
break | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The COMPLETED solution of Stav and Ofir - CLIENT (1-13) | |
# Imports | |
import socket | |
import sys | |
import select | |
import struct | |
import cPickle | |
import msvcrt | |
marshall = cPickle.dumps | |
unmarshall = cPickle.loads | |
# Constants | |
SERVER = '127.0.0.1' # TODO: Change this | |
PORT = 35000 | |
TIMEOUT = 0.1 # Timeout, in seconds, for select command | |
# Commands | |
COMMAND_SIZE = struct.calcsize("L") | |
SEND_MESSAGE_COMMAND = 1 # The command that represents sending a message] | |
KICK_USER_COMMAND = 2 | |
DECLARE_USER_NAME = 3 | |
ADD_ADMIN_COMMAND = 4 | |
VIEW_MANAGERS = 5 | |
MUTE_USER_COMMAND = 6 | |
PRIVATE_MSG_COMMAND = 7 | |
def send_size_and_argument(active_socket, argument): | |
'''Helper function used to send the length of an argument and then the argument itself. For example: 5, hello. | |
Receives: active_socket - the socket on which the parameters should be sent. | |
argument - the argument to send as a string. For example - hello. | |
Returns: nothing.''' | |
# Get the size to send it first | |
value = socket.htonl(len(argument)) | |
# Pack it | |
size = struct.pack("L",value) | |
# Send the size | |
active_socket.send(size) | |
# Send the argument | |
active_socket.send(argument) | |
def send_command(active_socket, command): | |
'''Helper function used to send a command. | |
Receives: active_socket - the socket on which the parameters should be sent. | |
command - the command to send. | |
Returns: nothing.''' | |
value = socket.htonl(command) | |
send_command = struct.pack("L", value) | |
active_socket.send(send_command) | |
def send_chat_message(active_socket, user_name, message): | |
'''Sends the chat message to the server using the fomrat of: | |
<user_name_length><user_name><SEND_MESSAGE_COMMAND><message_length><message> | |
Receives: | |
active_socket - the socket of connection with the server. | |
user_name - the user name of the writer. | |
message - the chat message to send. | |
Returns: nothing.''' | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, SEND_MESSAGE_COMMAND) | |
send_size_and_argument(active_socket, message) | |
def kick_user_from_chat(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, KICK_USER_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def declare_user_name(active_socket,user_name): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, DECLARE_USER_NAME) | |
send_size_and_argument(active_socket, user_name) | |
def add_admin(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, ADD_ADMIN_COMMAND) | |
message = message[4:] | |
send_size_and_argument(active_socket, message) | |
def view_managers(active_socket,user_name): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, VIEW_MANAGERS) | |
def mute_user(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, MUTE_USER_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def send_private_msg(active_socket, user_name, message): | |
send_size_and_argument(active_socket, user_name) | |
send_command(active_socket, PRIVATE_MSG_COMMAND) | |
message = message[5:] | |
send_size_and_argument(active_socket, message) | |
def receive_from_server(active_socket): | |
'''Function used to receive data from the server. | |
Receives: active_socket - the socket with the server. | |
Returns: data retrieved from the socket. | |
In case of an error - returns an empty string.''' | |
# Get the size of the data from the server | |
size_of_size = struct.calcsize("L") | |
size = active_socket.recv(size_of_size) | |
try: | |
# Try to parse the size of the given message. | |
size = socket.ntohl(struct.unpack("L", size)[0]) | |
except struct.error, e: | |
# In case of an error, return an empty string. | |
return '' | |
buf = "" | |
# Attempt to receive the whole message! | |
while len(buf) < size: | |
buf = active_socket.recv(size - len(buf)) | |
return unmarshall(buf)[0] | |
# Create the main socket - connection with the server | |
try: | |
# Create a TCP socket | |
# AF_INET means IPv4. | |
# SOCK_STREAM means a TCP connection. | |
# SOCK_DGRAM would mean an UDP "connection". | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
# Connect to the server | |
sock.connect((SERVER, PORT)) | |
print 'Connected to the server!' | |
# Grab user name from the user... | |
user_name = raw_input('Please choose a user name --> ') | |
declare_user_name(sock,user_name) | |
except socket.error, e: | |
# An error occurred | |
print 'Error connecting to server!' | |
# Quit | |
sys.exit(1) | |
# Run this loop forever... | |
input_from_user= '' | |
while True: | |
try: | |
# Wait for input from the server socket | |
rlist, wlist, xlist = select.select( [sock], [], [], TIMEOUT) | |
for current_socket in rlist: | |
# We have a message from the server! | |
data = receive_from_server(sock) | |
if data == "": | |
# We failed to receive data. The connection terminated. | |
print 'Shutting down.' | |
sys.exit(1) | |
else: | |
# We received the data successfully! Write it to the user! | |
print data | |
# Try to read from the user | |
# Note that this code is non blocking, so a read operation on the socket | |
# is also possible | |
# If any key was pressed | |
if msvcrt.kbhit(): | |
# Save the key that was pressed | |
keypressed = msvcrt.getch() | |
# Present the key on the screen for the user to see | |
sys.stdout.write(keypressed) | |
# if the key that was pressed was <Enter>: | |
if keypressed == '\r' or keypressed == '\n': | |
sys.stdout.write('\n') | |
# input_from_user is ready, so we can use it! | |
# We want to send the message to the server... | |
if 'KICK ' in input_from_user: | |
kick_user_from_chat(sock, user_name, input_from_user) | |
elif 'ADD ' in input_from_user: | |
add_admin(sock, user_name, input_from_user) | |
elif 'view-managers' == input_from_user: | |
view_managers(sock, user_name) | |
elif 'MUTE ' in input_from_user: | |
mute_user(sock, user_name, input_from_user) | |
elif 'SEND ' in input_from_user: | |
send_private_msg(sock, user_name, input_from_user) | |
else: | |
send_chat_message(sock, user_name, input_from_user) | |
# Initialize input_from_user | |
input_from_user = '' | |
else: | |
# input_from_user is not ready, so concate the pressed key | |
input_from_user += keypressed | |
except KeyboardInterrupt: | |
print 'Interrupted.' | |
sock.close() | |
break | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
import select | |
import socket | |
import time | |
import threading | |
import datetime | |
import math | |
TIME_WAIT = 0.01 | |
BIND_ADDR = 'localhost' | |
BIND_PORT = 33440 | |
SERV_ADDR = 'localhost' | |
SERV_PORT = 35000 | |
INTERVAL = 0.5 | |
def Route(): | |
i=0 | |
PADD=5 | |
listener = socket.socket() | |
listener.bind((BIND_ADDR, BIND_PORT)) | |
listener.listen(1) | |
client, caddr = listener.accept() | |
listener.close() | |
server = socket.socket() | |
server.connect((SERV_ADDR, SERV_PORT)) | |
running = True | |
temp= datetime.datetime.now() | |
while running: | |
try: | |
rlist = select.select([client, server], [], [])[0] | |
if client in rlist: | |
buf = client.recv(4096) | |
i+=1 | |
#print (i) | |
now= datetime.datetime.now() | |
current_delta=(now-temp).second | |
#current_delta= | |
ok_delta=0.01 | |
print current_delta | |
if current_delta > ok_delta: | |
print "bigger than sec" | |
else: | |
PADD-=1 | |
print "less than sec" | |
if PADD<0: | |
print "u kicked" | |
print (now-temp).microseconds | |
client.close() | |
running=False | |
temp= datetime.datetime.now() | |
if len(buf) == 0: | |
running = False | |
# Parse, modify, or halt traffic here | |
server.send(buf) | |
if server in rlist and running: | |
buf = server.recv(4096) | |
if len(buf) == 0: | |
running = False | |
# Parse, modify, or halt traffic here | |
client.send(buf) | |
except: | |
pass | |
temp=datetime.datetime.now() | |
try: | |
client.close() | |
except: | |
pass | |
try: | |
server.close() | |
except: | |
pass | |
if __name__ == '__main__': | |
Route() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
import select | |
import socket | |
import time | |
import threading | |
import datetime | |
TIME_WAIT = 0.01 | |
BIND_ADDR = 'localhost' | |
BIND_PORT = 33440 | |
SERV_ADDR = 'localhost' | |
SERV_PORT = 35000 | |
INTERVAL = 0.5 | |
def update(): | |
print "update" | |
global i | |
i+=1 | |
def set(): | |
global i | |
i=0 | |
def get(): | |
print "get" | |
global i | |
return i | |
def check_dos(): | |
global i | |
while True: | |
print get() | |
print "in check dos" | |
time.sleep(3) | |
def Route(): | |
listener = socket.socket() | |
listener.bind((BIND_ADDR, BIND_PORT)) | |
listener.listen(1) | |
client, caddr = listener.accept() | |
listener.close() | |
server = socket.socket() | |
server.connect((SERV_ADDR, SERV_PORT)) | |
running = True | |
set() | |
threading.Timer(1,check_dos()).start() | |
while running: | |
try: | |
rlist = select.select([client, server], [], [])[0] | |
if client in rlist: | |
buf = client.recv(4096) | |
#now= datetime.time | |
if len(buf) == 0: | |
running = False | |
# Parse, modify, or halt traffic here | |
update() | |
print get() | |
server.send(buf) | |
if server in rlist and running: | |
buf = server.recv(4096) | |
if len(buf) == 0: | |
running = False | |
# Parse, modify, or halt traffic here | |
client.send(buf) | |
except: | |
pass | |
try: | |
client.close() | |
except: | |
pass | |
try: | |
server.close() | |
except: | |
pass | |
if __name__ == '__main__': | |
Route() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import threading | |
import time | |
lock = threading.RLock() | |
def update(): | |
global i | |
i+=1 | |
def set(): | |
global i | |
i=0 | |
def get(): | |
global i | |
return i | |
def greeting(): | |
while True: | |
print get() | |
time.sleep(1) | |
set() | |
threading.Timer(1, greeting).start() | |
while True: | |
update() | |
time.sleep(0.5) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The COMPLETED solution of Stav and Ofir - SERVER (1-13) | |
# Imports | |
import select | |
import socket | |
import sys | |
import cPickle | |
import struct | |
import time | |
marshall = cPickle.dumps | |
unmarshall = cPickle.loads | |
# Constants | |
PORT = 35000 | |
MAX_LISTEN_CONNECTIONS = 5 | |
COMMAND_SIZE = struct.calcsize("L") | |
ADMINS = ['STAV','OFIR'] | |
# Commands | |
SEND_MESSAGE_COMMAND = 1 # The command that represents sending a message | |
KICK_USER_COMMAND = 2 | |
DECLARE_USER_NAME = 3 | |
ADD_ADMIN_COMMAND= 4 | |
VIEW_MANAGERS= 5 | |
MUTE_USER_COMMAND = 6 | |
PRIVATE_MSG_COMMAND = 7 | |
def receive_client_message(client_socket): | |
'''Receives the client message. | |
Receives: client_socket - the socket with the client. | |
Returns the message.''' | |
message = read_size_and_argument(client_socket) | |
return message | |
def receive_command_from_client(client_socket): | |
'''Receives a command from the client. | |
Receives: client_socket - the socket with the client. | |
Returns a tuple of (user_name, command)''' | |
user_name = read_size_and_argument(client_socket) | |
command = client_socket.recv(COMMAND_SIZE) | |
command = socket.ntohl(struct.unpack("L", command)[0]) | |
return (user_name, command) | |
def read_size_and_argument(client_socket): | |
'''Helper function used to read the size and argument from a client. | |
Receives: client_socket - the socket with the client. | |
Returns: only the argument, as a string.''' | |
# Get the size of the data from the server | |
size = struct.calcsize("L") | |
size = client_socket.recv(size) | |
if len(size) == 0: | |
# The connection has been terminated by the user | |
raise socket.error | |
try: | |
# Try to parse the size of the given message. | |
size = socket.ntohl(struct.unpack("L", size)[0]) | |
except struct.error, e: | |
# In case of an error, return an empty string. | |
return '' | |
buf = "" | |
# Attempt to receive the whole message! | |
while len(buf) < size: | |
buf = client_socket.recv(size - len(buf)) | |
return buf | |
def server_send(active_socket, *arguments): | |
'''Provides send functionality. | |
Receives: active_socket - the socket on which the parameters should be sent. | |
*arguments - list of arguments to send. | |
Returns nothing.''' | |
# First - put all the arguments in a buffer | |
buf = marshall(arguments) | |
# Get the size to send it first | |
value = socket.htonl(len(buf)) | |
# Pack it | |
size = struct.pack("L",value) | |
active_socket.send(size) | |
active_socket.send(buf) | |
def get_current_time(): | |
'''Retrieves the current time in a known format. | |
Receives: nothing. | |
Returnes: the current time as a string, format of <hour>:<minute>''' | |
return time.strftime('%H:%M') | |
def send_user_left_message(user_name, open_sockets): | |
''' Sends all connected users a message declaring the | |
disconnection of a user ''' | |
text = user_name + " has left the chat!" | |
message = '%s %s' % (get_current_time(), text) | |
# Send the message to other clients | |
clients_to_send = [] | |
for sock in open_sockets: | |
if sock == current_socket: | |
continue | |
clients_to_send.append(sock) | |
messages_to_send.append((message, clients_to_send)) | |
def send_user_kicked_message(user_name, open_sockets): | |
''' Sends all connected users a message declaring the | |
kick of a user ''' | |
text = user_name + " was kicked from the chat!" | |
message = '%s %s' % (get_current_time(), text) | |
# Send the message to other clients | |
clients_to_send = [] | |
for sock in open_sockets: | |
if sock == current_socket: | |
continue | |
clients_to_send.append(sock) | |
messages_to_send.append((message, clients_to_send)) | |
def send_waiting_messages(wlist): | |
'''Sends waiting messages to all clients that the message has not yet been | |
sent to, and that have a writable socket. | |
Receives: wlist - a list of all currently writable sockets. | |
NOTE: Based on global messages_to_send - a list of messages that | |
needed to be sent, as a tuple of: (message, [sockets]) | |
Returns nothing.''' | |
global messages_to_send # Declare global list | |
# Iterate through all messages to send | |
for message in messages_to_send: | |
(message_text, clients) = message | |
# For every client that still needs to receive this message | |
for client in clients: | |
# If the socket for the client is writable | |
if client in wlist: | |
server_send(client, message_text) | |
# Now that we sent it, we can clear it off the list | |
clients.remove(client) | |
def send_message_cmd(current_socket,open_sockets,user_name, muted_users): | |
# Receive message from the client | |
client_message = receive_client_message(current_socket) | |
if client_message == "quit": | |
current_socket.close() | |
print user_name + ' disconnected' | |
open_sockets.remove(current_socket) | |
send_user_left_message(user_name, open_sockets) | |
# Format it as <time> <user_name>: <message> | |
elif user_name in muted_users: | |
server_send(current_socket, 'You cannot speak here.') | |
else: | |
if user_name in ADMINS: | |
client_message = '%s %s: %s' % (get_current_time(),"@"+user_name, client_message) | |
else: | |
client_message = '%s %s: %s' % (get_current_time(), user_name, client_message) | |
# Send the message to other clients | |
clients_to_send = [] | |
for sock in open_sockets: | |
if sock == current_socket: | |
continue | |
clients_to_send.append(sock) | |
messages_to_send.append((client_message, clients_to_send)) | |
def kick_user_cmd(current_socket,open_sockets,user_name,username_sockets_dict): | |
client_message = receive_client_message(current_socket) | |
# Receive kick command | |
if user_name in ADMINS and client_message in username_sockets_dict: | |
username_sockets_dict[client_message].close() | |
print user_name + ' kicked ' + client_message | |
open_sockets.remove(username_sockets_dict[client_message]) | |
send_user_left_message(client_message, open_sockets) | |
else: | |
print user_name + ' tried to kick' | |
def declare_user_cmd(current_socket,open_sockets,user_name): | |
client_message = receive_client_message(current_socket) | |
# Receive declare command | |
if client_message[0] == '@' or user_name in username_sockets_dict: | |
server_send(current_socket, 'Username invalid, try again') | |
open_sockets.remove(current_socket) | |
current_socket.close() | |
else: | |
username_sockets_dict[client_message] = current_socket | |
print user_name + ' has signed in' | |
def add_admin_cmd(current_socket,open_sockets,user_name,username_sockets_dict): | |
client_message = receive_client_message(current_socket) | |
# Receive add command | |
if user_name in ADMINS and client_message not in ADMINS and client_message in username_sockets_dict: | |
ADMINS.append(client_message) | |
print user_name + ' added ' + client_message + ' to the admin list' | |
else: | |
print user_name + ' tried to add' | |
def mute_user_cmd(current_socket,open_sockets,user_name,username_sockets_dict, muted_users): | |
client_message = receive_client_message(current_socket) | |
# Receive mute command | |
if user_name in ADMINS and client_message in username_sockets_dict and client_message not in muted_users: | |
muted_users.append(client_message) | |
print user_name + ' muted ' + client_message | |
else: | |
print user_name + ' tried to mute' | |
def private_msg_cmd(current_socket, open_sockets, user_name, username_sockets_dict): | |
client_message = receive_client_message(current_socket) | |
# Receive private message | |
data = client_message.split(': ') | |
server_send(username_sockets_dict[data[0]],'%s !%s: %s' % (get_current_time(),user_name, data[1])) | |
# AF_INET means IPv4. | |
# SOCK_STREAM means a TCP connection. | |
# SOCK_DGRAM would mean an UDP "connection". | |
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
# The parameter is (host, port). | |
# The host, when empty or when 0.0.0.0, means to accept connections for | |
# all IP addresses of current machine. Otherwise, the socket will bind | |
# itself only to one IP. | |
# The port must greater than 1023 if you plan running this script as a | |
# normal user. Ports below 1024 require root privileges. | |
server.bind(('',PORT)) | |
print 'Listening!' | |
# The parameter defines how many new connections can wait in queue. | |
# Note that this is NOT the number of open connections (which has no limit). | |
# Read listen(2) man page for more information. | |
server.listen(MAX_LISTEN_CONNECTIONS) | |
# Output socket list | |
# List of socket objects that are currently open | |
open_sockets = [] | |
username_sockets_dict = {} | |
messages_to_send = [] | |
muted_users = [] | |
while True: | |
rlist, wlist, xlist = select.select( [server] + open_sockets, open_sockets, [] ) | |
for current_socket in rlist: | |
if current_socket == server: | |
# A new connection has been received! | |
# Handle the socket | |
(client, address) = server.accept() | |
print 'New connection from %s' % (address,) | |
open_sockets.append(client) | |
else: | |
# Data has been received from the client, process it | |
try: | |
(user_name, client_command) = receive_command_from_client(current_socket) | |
if client_command == SEND_MESSAGE_COMMAND: | |
send_message_cmd(current_socket,open_sockets,user_name, muted_users) | |
elif client_command == KICK_USER_COMMAND: | |
kick_user_cmd(current_socket,open_sockets,user_name,username_sockets_dict) | |
elif client_command == DECLARE_USER_NAME: | |
declare_user_cmd(current_socket,open_sockets,user_name) | |
elif client_command == ADD_ADMIN_COMMAND: | |
add_admin_cmd(current_socket,open_sockets,user_name,username_sockets_dict) | |
elif client_command == VIEW_MANAGERS: | |
server_send(current_socket, ADMINS) | |
elif client_command == MUTE_USER_COMMAND: | |
mute_user_cmd(current_socket,open_sockets,user_name,username_sockets_dict, muted_users) | |
elif client_command == PRIVATE_MSG_COMMAND: | |
private_msg_cmd(current_socket, open_sockets, user_name, username_sockets_dict) | |
# TODO: Add handling for more commands here! | |
else: | |
# Unknown command received | |
current_socket.close() | |
open_sockets.remove(current_socket) | |
send_user_left_message(user_name, open_sockets) | |
except socket.error, e: | |
# Remove | |
print user_name + ' disconnected' | |
open_sockets.remove(current_socket) | |
send_user_left_message(user_name, open_sockets) | |
try: | |
send_waiting_messages(wlist) | |
except socket.error, e: | |
# Remove | |
print user_name + ' disconnected' | |
open_sockets.remove(current_socket) | |
send_user_left_message(user_name, open_sockets) | |
# Finish running! | |
server.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment