Author: Cristian Stefan Totolin | Language: python |
Description: Not specified | Timestamp: 2017-07-02 17:53:51 +0000 |
View raw paste | Reply |
"""
Module that takes care of socket communication from/to MASFRL-Client
instances. Manages all clients, storing them by their credentials.
"""
import socket
import sys
import logging
import time
import masfrl.messages as messages
logger = logging.getLogger(__name__)
class ConnectionManager:
def __init__(self, host, port):
"""
Constructor for the ConnectionManager class.
:param host: host address to listen on
:param port: port to listen on
"""
logger.debug('Creating a Connection Manager')
# Save future clients in a map
self.clients = {}
# Create a TCP/IP socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
self.server_address = (host, port)
def start_listening(self, max_connections=1):
"""
Binds created address to socket, and stars listening
for incoming connections.
:param max_connections: maximum number of queued connections
:return:
"""
try:
# Bind address tuple to socket
self.sock.bind(self.server_address)
# Listen for incoming connections
self.sock.listen(max_connections)
except socket.error as err:
# Listening to desired port failed
logger.error(err)
sys.exit(1)
logger.info('Server started on %s' % (self.server_address,))
def wait_for_connections(self, expected, timeout=1000):
"""
Waits for expected number of clients
:param expected: integer - number of expected clients
:param timeout: maximum time to wait for clients
:return:
"""
logger.info('Waiting for %s connections' % expected)
start = time.time()
while True:
# Break if we exceeded timeout
current = time.time()
if current - start >= timeout:
break
# Wait for a connection
connection, client_address = self.sock.accept()
# Save connection
self.clients[str(client_address)] = {
"connection": connection,
"work": None
}
logger.info('Received connection from %s' % str(client_address))
if len(self.clients) == expected:
logger.info('All clients connected')
break
return True if len(self.clients) == expected else False
def send_message(self, client_address, message):
"""
Sends a client defined by it's address a message
:param client_address: MASFRL-Client address
:param message: message to be encoded
:return:
"""
encoded = messages.encode_message(message)
self.clients[client_address]['connection'].send(encoded)
logger.debug('Sent message to client %s' % client_address)
def receive_message(self, client_address):
"""
Waits for a client to send a message
:param client_address: MASFRL-Client address
:return: decoded message
"""
logger.debug('Waiting for message from client %s' % client_address)
# Grab connection object from our map
connection = self.clients[client_address]['connection']
message = ''
while True:
# Continuously receive chunks
data = connection.recv(1024)
if data:
message += data
if messages.stream_stop(data):
break
logger.debug('Received encoded message')
return messages.decode_message(message)
Module that takes care of socket communication from/to MASFRL-Client
instances. Manages all clients, storing them by their credentials.
"""
import socket
import sys
import logging
import time
import masfrl.messages as messages
logger = logging.getLogger(__name__)
class ConnectionManager:
def __init__(self, host, port):
"""
Constructor for the ConnectionManager class.
:param host: host address to listen on
:param port: port to listen on
"""
logger.debug('Creating a Connection Manager')
# Save future clients in a map
self.clients = {}
# Create a TCP/IP socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
self.server_address = (host, port)
def start_listening(self, max_connections=1):
"""
Binds created address to socket, and stars listening
for incoming connections.
:param max_connections: maximum number of queued connections
:return:
"""
try:
# Bind address tuple to socket
self.sock.bind(self.server_address)
# Listen for incoming connections
self.sock.listen(max_connections)
except socket.error as err:
# Listening to desired port failed
logger.error(err)
sys.exit(1)
logger.info('Server started on %s' % (self.server_address,))
def wait_for_connections(self, expected, timeout=1000):
"""
Waits for expected number of clients
:param expected: integer - number of expected clients
:param timeout: maximum time to wait for clients
:return:
"""
logger.info('Waiting for %s connections' % expected)
start = time.time()
while True:
# Break if we exceeded timeout
current = time.time()
if current - start >= timeout:
break
# Wait for a connection
connection, client_address = self.sock.accept()
# Save connection
self.clients[str(client_address)] = {
"connection": connection,
"work": None
}
logger.info('Received connection from %s' % str(client_address))
if len(self.clients) == expected:
logger.info('All clients connected')
break
return True if len(self.clients) == expected else False
def send_message(self, client_address, message):
"""
Sends a client defined by it's address a message
:param client_address: MASFRL-Client address
:param message: message to be encoded
:return:
"""
encoded = messages.encode_message(message)
self.clients[client_address]['connection'].send(encoded)
logger.debug('Sent message to client %s' % client_address)
def receive_message(self, client_address):
"""
Waits for a client to send a message
:param client_address: MASFRL-Client address
:return: decoded message
"""
logger.debug('Waiting for message from client %s' % client_address)
# Grab connection object from our map
connection = self.clients[client_address]['connection']
message = ''
while True:
# Continuously receive chunks
data = connection.recv(1024)
if data:
message += data
if messages.stream_stop(data):
break
logger.debug('Received encoded message')
return messages.decode_message(message)
View raw paste | Reply |