Skip to content

Commit

Permalink
TCP connection handling added
Browse files Browse the repository at this point in the history
  • Loading branch information
mmuravytskyi committed Jun 12, 2021
1 parent a02d079 commit 7b49e73
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 10 deletions.
6 changes: 4 additions & 2 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
MULTICAST_PORT = 10000
MULTICAST_IP = '224.0.0.1'
MULTICAST_PORT = 10001
MULTICAST_IP = '224.0.0.1'
TCP_PORT = 10001
SERVER_IP = 'localhost'
77 changes: 74 additions & 3 deletions daemon_file.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
import logging
import socket
import config
import json
import struct
import threading
import time
import os
from daemon import runner
from datetime import datetime

client_base = { "clients":
[
{
"address": "192.168.0.1",
"port": "2208",
"nickname": "nikita",
"online": True
},
{
"address": "192.168.0.2",
"port": "2208",
"nickname": "pobeda",
"online": False
},
]
}


class App():
def __init__(self):
Expand All @@ -12,15 +34,64 @@ def __init__(self):
self.stderr_path = '/dev/null'
self.pidfile_path = os.path.join(os.getcwd(), 'multiproto.pid')
self.pidfile_timeout = 5

def run(self):
while True:
# logger.debug("Debug message")
# logger.info("Info message")
# logger.warn("Warning message")
# logger.error("Error message")
logger.info(f'LOG: {datetime.now()}')
time.sleep(5)
# logger.info(f'LOG: {datetime.now()}')
self.multicast_handler()

@staticmethod
def tcp_handler(client_address):
# TCP socket creation
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(client_address)

# convert dict structure to bytes
msg = json.dumps(client_base).encode('utf-8')

try:
sock.sendall(msg)
finally:
print('closing socket')
sock.close()
pass

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

# UDP socket creation
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# bind to the server address
sock.bind(server_address)

# IP string to bytes conversion
mcast_group = socket.inet_aton(config.MULTICAST_IP)
# listen on all interfaces `socket.INADDR_ANY`
mreq = struct.pack('4sL', mcast_group, socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

# Receive/respond loop
while True:
print('\nwaiting to receive message')
logger.info(f'Listening for multicast messages')
data, address = sock.recvfrom(1024)

print('received %s bytes from %s' % (len(data), address))
logger.info(f'Received multicast message from {address}')
print(data)

print('sending acknowledgement to', address)
logger.info(f'Starting TCP session with {address}')
# call TCP session
thread = threading.Thread(target=self.tcp_handler, args=address)
# run thread in the background as daemon
thread.daemon = True
thread.start()
# sock.sendto(json.dumps(client_base).encode('utf-8'), address)


if __name__ == '__main__':
Expand Down
44 changes: 42 additions & 2 deletions multicast_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,51 @@
import struct
import sys
import config
import json
import threading

message = 'SERVER DISCOVERY'
multicast_group = (config.MULTICAST_IP, config.MULTICAST_PORT)


def tcp_handler():
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (config.SERVER_IP, config.TCP_PORT)
sock_tcp.bind(server_address)

sock_tcp.listen(1)

while True:
# Wait for a connection
print('waiting for a connection')
connection, client_address = sock.accept()
try:
print(sys.stderr, 'connection from', client_address)

# Receive the data in small chunks and retransmit it
while True:
data = connection.recv(16)
print('received "%s"' % data)
if data:
print('sending data back to the client')
connection.sendall(data)
else:
print('no more data from', client_address)
break
finally:
# Clean up the connection
connection.close()


thread = threading.Thread(target=tcp_handler, args=())
# run thread in the background as daemon
# thread.daemon = True
thread.start()

# Create the datagram socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


# Set a timeout so the socket does not block indefinitely when trying
# to receive data.
sock.settimeout(0.2)
Expand All @@ -28,13 +66,15 @@
while True:
print('waiting to receive')
try:
data, server = sock.recvfrom(16)
data, server = sock.recvfrom(1024)
except socket.timeout:
print('timed out, no more responses')
break
else:
print('received "%s" from %s' % (data, server))
res_dict = json.loads(data.decode('utf-8'))
print(res_dict)

finally:
print('closing socket')
sock.close()
# sock_tcp.close()
23 changes: 20 additions & 3 deletions multicast_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
import struct
import sys
import config
import json

client_base = { "clients":
[
{
"address": "192.168.0.1",
"port": "2208",
"nickname": "nikita",
"online": True
},
{
"address": "192.168.0.2",
"port": "2208",
"nickname": "pobeda",
"online": False
},
]
}

server_address = ('', config.MULTICAST_PORT)

Expand All @@ -11,8 +29,7 @@
# Bind to the server address
sock.bind(server_address)

# Tell the operating system to add the socket to the multicast group
# on all interfaces.
# Tell the operating system to add the socket to the multicast group on all interfaces.
mcast_group = socket.inet_aton(config.MULTICAST_IP)
mreq = struct.pack('4sL', mcast_group, socket.INADDR_ANY) # listen on all interfaces `socket.INADDR_ANY`
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
Expand All @@ -26,4 +43,4 @@
print(data)

print('sending acknowledgement to', address)
sock.sendto(bytes('ack', encoding='utf-8'), address)
sock.sendto(json.dumps(client_base).encode('utf-8'), address)

0 comments on commit 7b49e73

Please sign in to comment.