Skip to content

Commit

Permalink
integration done
Browse files Browse the repository at this point in the history
  • Loading branch information
netrsr committed Jun 24, 2021
1 parent d5b42ee commit 3af2944
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 38 deletions.
40 changes: 23 additions & 17 deletions client_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import config
import sctp
import json
import os
import threading
import random

Expand All @@ -20,28 +21,28 @@ class Client():
def __init__(self):
self.client_list = dict()
self.username = ''
self.stcp_sock = object

@staticmethod
def sctp_handler(client_port: int):

def sctp_handler(self, client_port: int):
# SCTP socket creation
sock = sctp.sctpsocket_udp(socket.AF_INET)
# get notifications on assoc state
tmp = sctp.event_subscribe(sock)
tmp.set_association(1)
tmp.set_data_io(1)
self.stcp_sock = sock
sock.autoclose = 0
sock.bind(('', client_port))

sock.sctp_send(msg=b'0', to=(config.SERVER_IP, config.SCTP_PORT))
while True:
try:
fromaddr, flags, msgret, notif = sock.sctp_recv(2048)
if notif.state == 3:
print(f'Client {sock.getpaddr(notif.assoc_id)} is down.')
elif notif.state == 0:
print.info(f'Client {sock.getpaddr(notif.assoc_id)} is up.')
print(f'CLIENT: Received an update of client base')

client_list = json.loads(msgret.decode('utf-8'))
self.client_list = client_list
except:
pass


@staticmethod
def multicast_handler(client_port: int):
# create the datagram socket
Expand Down Expand Up @@ -101,8 +102,7 @@ def tcp_handler(self, _port: int):
def tcp_listener(_port: int):
s = socket.socket()
# host = socket.gethostname()
host = '0.0.0.0'
s.bind((host, _port))
s.bind(('', _port))
s.listen(5)
print('TCP listener started on port', _port)

Expand All @@ -124,9 +124,12 @@ def tcp_listener(_port: int):
@staticmethod
def do_list(clients: List):
print("Available clients:")

for client in clients:
print(f'address: {client["ip"]}:{client["port"]}, nickname: {client["nickname"]}')
if not client['online']:
print(f'address: {client["ip"]}:{client["port"]}, nickname: {client["nickname"]} *offline*')
else:
print(f'address: {client["ip"]}:{client["port"]}, nickname: {client["nickname"]} *online*')


@staticmethod
def do_connect(address: Dict, _username: str) -> bool:
Expand Down Expand Up @@ -173,7 +176,6 @@ def handle_actions(self, clients: List, _username: str):
client = {}
# check if client_address is an IP:port string or client name
cli_filtered = list(filter(lambda c: c['nickname'] == client_address, clients))
print(cli_filtered)
if len(cli_filtered): # client name found -> assign client
client['ip'] = cli_filtered[0]['ip']
# TODO: change this +1
Expand All @@ -195,7 +197,8 @@ def handle_actions(self, clients: List, _username: str):

if action == 'exit':
print('Exiting...')
sys.exit(1)
self.stcp_sock.close()
os._exit(1)


if __name__ == '__main__':
Expand All @@ -211,11 +214,14 @@ def handle_actions(self, clients: List, _username: str):
port = random.randint(50_000, 65_000)
# pass selected port to the TCP thread, in order to listen on the same port
# thread in the background as daemon
th = threading.Thread(target=s.tcp_handler, args=(port,), daemon=True)
th = threading.Thread(target=s.tcp_handler, args=(port,))
th.start()
s.multicast_handler(port)
th.join()

th_ = threading.Thread(target=s.sctp_handler, args=(port,))
th_.start()

print(s.client_list)

# TODO: smart port allocation
Expand Down
72 changes: 51 additions & 21 deletions daemon_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,9 @@
from daemon import runner


client_base = {"clients": [
{
"ip": "192.168.0.1",
"port": 2250,
"nickname": "pepka",
"online": True
}
]}
client_base = {"clients": []}

cli_assoc = dict()


class App():
Expand All @@ -29,6 +24,9 @@ def __init__(self):
self.pidfile_timeout = 5

def run(self):
thread = threading.Thread(target=self.sctp_handler, args=(), daemon=True)
# run thread in the background as daemon
thread.start()
while True:
# main thread
self.multicast_handler()
Expand Down Expand Up @@ -72,28 +70,64 @@ def tcp_handler(address):
sock.close()

@staticmethod
def sctp_handler(address):
logger.info(f'Starting STCP session for {address}')
def update_client_base(socket):
for client in client_base['clients']:
if client['online'] == True:
_ = (client['ip'], client['port'])
logger.info(f'Sending client base update to...{_[0]}:{_[1]}')
# do not send the client its own information
_tmp = {"clients":
[
x for x in client_base['clients'] if x['ip']!= client['ip'] or x['port']!= client['port']
]
}
if _tmp['clients']:
# convert dict structure to bytes
logger.info(_tmp)
msg = json.dumps(_tmp).encode('utf-8')
socket.sctp_send(msg, to=_)

def sctp_handler(self):
logger.info(f'Starting STCP session')
# SCTP socket creation
sock = sctp.sctpsocket_udp(socket.AF_INET)
# get notifications on assoc state
tmp = sctp.event_subscribe(sock)
tmp.set_association(1)
tmp.set_data_io(1)
sock.autoclose = 0
sock.bind(('', config.SCTP_PORT))
sock.sctp_send(msg=b'0', to=address)
sock.listen(5)

while True:
try:
fromaddr, flags, msgret, notif = sock.sctp_recv(2048)
if notif.state == 3:
logger.info(f'Client {sock.getpaddr(notif.assoc_id)} is down.')
elif notif.state == 0:
logger.info(f'Client {sock.getpaddr(notif.assoc_id)} is up.')
_ = cli_assoc[notif.assoc_id]
del cli_assoc[notif.assoc_id]
logger.info(f'Client {_[0]}:{_[1]} is down.')

for client in client_base['clients']:
if client['ip'] == _[0] and client['port'] == _[1] and client['online']==True:
client['online'] = False

self.update_client_base(sock)

else:
_ = sock.getpaddrs(notif.assoc_id)[1]
logger.info(f'Client {_[0]}:{_[1]} is up.')
# assign association id to the client
cli_assoc[notif.assoc_id] = _

for client in client_base['clients']:
if client['ip'] == _[0] and client['port'] == _[1] and client['online']==False:
client['online'] = True

self.update_client_base(sock)

except:
pass



def multicast_handler(self):
server_address = ('', config.MULTICAST_PORT)

Expand All @@ -113,15 +147,11 @@ def multicast_handler(self):
logger.info(f'Listening for multicast messages')
data, address = sock.recvfrom(1024)
logger.info(f'Received multicast message from {address}')

# call TCP session
thread = threading.Thread(target=self.tcp_handler, args=(address,), daemon=True)
# run thread in the background as daemon
thread.start()
# call SCTP session
_thread = threading.Thread(target=self.sctp_handler, args=(address,), daemon=True)
# run thread in the background as daemon
_thread.start()



if __name__ == '__main__':
Expand Down

0 comments on commit 3af2944

Please sign in to comment.