feat: complete service exploration

This commit is contained in:
Ting-Jun Wang 2024-05-18 01:46:39 +08:00
parent b1de4dcacd
commit 4fa614776d
Signed by: snsd0805
GPG Key ID: 48D331A3D6160354
4 changed files with 73 additions and 73 deletions

View File

@ -1,73 +0,0 @@
import socket
import argparse
import threading
import random
import time
def handle_client(conn):
while True:
try:
num = random.randint(0, 100)
conn.send(f"number={num}".encode())
time.sleep(1)
except:
print("Disconnected.")
conn.close()
break
class ServiceExplorationModule():
def __init__(self, host, port):
# UDP server
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.host = host
self.port = port
self.is_available = False
def listen(self):
self.sock.bind((self.host, self.port))
print(f"Exploration Server(UDP) listening on port {self.port}...")
while True:
data, addr = self.sock.recvfrom(1024)
if self.is_available:
if data.decode() == '[EXPLORE]':
print(f"Receive exploration broadcast from {addr}")
self.sock.sendto(self.host.encode(), addr)
def explore(self):
available_host = []
self.sock.settimeout(3)
self.sock.sendto('[EXPLORE]'.encode(), ('255.255.255.255', self.port))
while True:
try:
data, addr = self.sock.recvfrom(1024)
available_host.append(addr)
print(data.decode(), addr)
except:
# if socket timeout
break
return available_host
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('type', type=str, help="'client' or 'server'", default='server')
parser.add_argument('--host', type=str, help="server's IPv4 address", default='0.0.0.0')
parser.add_argument('--port', type=int, help="server's listening port", default=8888)
args = parser.parse_args()
socket_type = args.type
host, port = args.host, args.port
service_explore = ServiceExplorationModule(host, port)
explore_service_thread = threading.Thread(target=service_explore.listen)
explore_service_thread.start()
if socket_type == 'client':
hosts = service_explore.explore()
print(hosts)

21
main.py Normal file
View File

@ -0,0 +1,21 @@
import argparse
import threading
from src.communication import ServiceExplorationModule
from src.parser import get_args
if __name__ == '__main__':
args = get_args()
socket_type = args.type
host, port = args.host, args.port
# start Service Exploration Module
# let all client can know which IP address has our service so that it can link to.
service_explore = ServiceExplorationModule(host, port+1)
explore_service_thread = threading.Thread(target=service_explore.listen)
explore_service_thread.start()
if socket_type == 'client':
hosts = service_explore.explore()
print(hosts)

42
src/communication.py Normal file
View File

@ -0,0 +1,42 @@
import socket
class ServiceExplorationModule():
def __init__(self, host, port):
# UDP server
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
self.host = host
self.port = port
self.IP = socket.gethostbyname(socket.gethostname())
self.is_available = True
def listen(self):
self.sock.bind((self.host, self.port))
print(f"Exploration Server(UDP) listening on {self.host}:{self.port}...")
while True:
data, addr = self.sock.recvfrom(1024)
if self.is_available:
if data.decode() == '[EXPLORE]':
print(f"Receive exploration broadcast from {addr}")
self.sock.sendto(self.IP.encode(), addr)
def explore(self):
available_host = []
client_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
client_sock.settimeout(3)
client_sock.sendto('[EXPLORE]'.encode(), ('255.255.255.255', self.port))
while True:
try:
data, addr = client_sock.recvfrom(1024)
if addr[0] != self.IP:
available_host.append(addr)
except:
# if socket timeout
break
return available_host

10
src/parser.py Normal file
View File

@ -0,0 +1,10 @@
import argparse
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('type', type=str, help="'client' or 'server'", default='server')
parser.add_argument('--host', type=str, help="server's IPv4 address", default='0.0.0.0')
parser.add_argument('--port', type=int, help="server's listening port", default=8888)
args = parser.parse_args()
return args