pdc_project/client.py
2025-05-19 19:44:29 +02:00

86 lines
No EOL
3.4 KiB
Python

# ############################################################################
# client.py for PDC 2025 (DO NOT EDIT!!)
# =========
# Original Author : Sepand KASHANI [sepand.kashani@epfl.ch]
# Current version: Adway Girish [adway.girish@epfl.ch]
# ############################################################################
"""
Black-box channel simulator. (client)
Instructions
------------
python3 client.py --input_file=[FILENAME] --output_file=[FILENAME] --srv_hostname=[HOSTNAME] --srv_port=[PORT]
"""
import argparse
import pathlib
import socket
import numpy as np
import channel_helper as ch
def parse_args():
parser = argparse.ArgumentParser(description="COM-302 black-box channel simulator. (client)",
formatter_class=argparse.RawTextHelpFormatter,
epilog="To promote efficient communication schemes, transmissions are limited to 1 Mega-sample.")
parser.add_argument('--input_file', type=str, required=True,
help='.txt file containing (N_sample,) rows of float samples.')
parser.add_argument('--output_file', type=str, required=True,
help='.txt file to which channel output is saved.')
parser.add_argument('--srv_hostname', type=str, required=True,
help='Server IP address.')
parser.add_argument('--srv_port', type=int, required=True,
help='Server port.')
args = parser.parse_args()
args.input_file = pathlib.Path(args.input_file).resolve(strict=True)
if not (args.input_file.is_file() and
(args.input_file.suffix == '.txt')):
raise ValueError('Parameter[input_file] is not a .txt file.')
args.output_file = pathlib.Path(args.output_file).resolve(strict=False)
if not (args.output_file.suffix == '.txt'):
raise ValueError('Parameter[output_file] is not a .txt file.')
return args
if __name__ == '__main__':
version_cl = b'dUV' # Always length-3 alphanumeric
args = parse_args()
tx_p_signal = np.loadtxt(args.input_file)
N_sample = tx_p_signal.size
if not ((tx_p_signal.shape == (N_sample,)) and
np.issubdtype(tx_p_signal.dtype, np.floating)):
raise ValueError('Parameter[input_file] must contain a real-valued sequence.')
if N_sample > 1000000:
raise ValueError(('Parameter[input_file] contains more than 1,000,000 samples. '
'Design a more efficient communication system.'))
energy = np.sum(np.square(np.abs(tx_p_signal)))
if energy > 2000:
raise ValueError(('Energy of the signal exceeds the limit 2,000. '
'Design a more efficient communication system.'))
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) as sock_cl:
sock_cl.connect((args.srv_hostname, args.srv_port))
tx_header = b'0' + version_cl
ch.send_msg(sock_cl, tx_header, tx_p_signal)
rx_header, rx_data = ch.recv_msg(sock_cl)
if rx_header[:1] == b'0': # Data
np.savetxt(args.output_file, rx_data)
elif rx_header[:1] == b'1': # Rate limit
raise Exception(rx_data.tobytes())
elif rx_header[:1] == b'2': # Outdated version of client.py
raise Exception(rx_data.tobytes())
else: # Unknown header
err_msg = f'Unknown header: {rx_header}'
raise Exception(err_msg)