0% found this document useful (0 votes)
26 views4 pages

Client cst311

Uploaded by

api-635181702
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views4 pages

Client cst311

Uploaded by

api-635181702
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

#!

env python

"""Chat client for CST311 Programming Assignment 4"""


__author__ = "Bitwise"
__credits__ = [
"Chris McMichael",
"Jake Kroeker",
"Jeremiah McGrath",
"Miguel Jimenez"
]

# Import statements
import PA4_Server_Team1 as server
import select
import socket as s
import ssl
import sys
import threading as t
import time

# Configure logging
import logging
logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

# Constants
SERVER_NAME = server.SERVER_NAME
SERVER_PORT = server.SERVER_PORT
RETRY_COUNT = 5
RETRY_WAIT = 1
BYE_COMMAND = server.BYE_COMMAND

# Global variables
running = True

# Handles receiving server responses


def receive_handler(socket):
global running
while running:
# Read response from server
server_response = socket.recv(1024).decode()

# Parse "bye" command


if (index := server_response.find(" : ")) != -1:
message = server_response[index + 3:]
if message.lower() == BYE_COMMAND:
running = False

# Prevents invalid output on chat termination


if server_response != "":
# Print output from server
print(server_response)

# Handles sending messages to the server


def send_handler(socket):
global running
while running:
# [IMPORTANT] select.select() is UNIX ONLY, this script doesn't
work on Windows!
# Tests whether the user has typed a line and pressed enter
# Blocks for 0.1 seconds if a line isn't ready; the timeout allows
the thread to react to running = False
if select.select([sys.stdin], [], [], 0.1)[0]:
# Send data across socket to server
# Note: encode() converts the string to UTF-8 for
transmission
user_input = input()
socket.send(user_input.encode())

if user_input.lower() == BYE_COMMAND:
running = False

def main():
# Create socket
ssl_context = ssl.create_default_context()
client_socket = s.socket(s.AF_INET, s.SOCK_STREAM)
secure_socket = ssl_context.wrap_socket(client_socket,
server_hostname=SERVER_NAME)
retry_counter = 0

while True:

try:
# Establish TLS connection
secure_socket.connect((SERVER_NAME, SERVER_PORT))
break

except Exception as e:

if isinstance(e, ConnectionRefusedError) and retry_counter <


RETRY_COUNT:
retry_counter += 1
# Uncomment this line if you want to log connection retry
attempts
# log.warning(f"Retrying connection; attempt
{retry_counter}/{RETRY_COUNT} ...")
time.sleep(RETRY_WAIT)
else:
log.exception(e)
log.error("***Advice:***")

if isinstance(e, s.gaierror):
log.error("\tCheck that server_addr and server_port
are set correctly.")
elif isinstance(e, ConnectionRefusedError):
log.error("\tCheck that server is running and the
address is correct")
else:
log.error("\tNo specific advice, please contact
teaching staff and include text of error and code.")

exit(8)

# Wrap in a try-finally to ensure the socket is properly closed


regardless of errors
try:
# Create receive and send threads
receive_thread: t.Thread = t.Thread(target=receive_handler,
args=(secure_socket,))
send_thread: t.Thread = t.Thread(target=send_handler,
args=(secure_socket,))

# Start receive and send threads


receive_thread.start()
send_thread.start()

# Wait for receive and send threads


receive_thread.join()
send_thread.join()

finally:
# Close socket prior to exit
secure_socket.close()

# This helps shield code from running when we import the module
if __name__ == "__main__":
main()

You might also like