-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathchat_client.py
110 lines (85 loc) · 3.27 KB
/
chat_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import select
import socket
import sys
import signal
import argparse
import threading
import ssl
from utils import *
SERVER_HOST = 'localhost'
stop_thread = False
def get_and_send(client):
while not stop_thread:
data = sys.stdin.readline().strip()
if data:
send(client.sock, data)
class ChatClient():
""" A command line chat client using select """
def __init__(self, name, port, host=SERVER_HOST):
self.name = name
self.connected = False
self.host = host
self.port = port
self.context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# Initial prompt
self.prompt = f'[{name}@{socket.gethostname()}]> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock = self.context.wrap_socket(
self.sock, server_hostname=host)
self.sock.connect((host, self.port))
print(f'Now connected to chat server@ port {self.port}')
self.connected = True
# Send my name...
send(self.sock, 'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '@'.join((self.name, addr)) + ']> '
threading.Thread(target=get_and_send, args=(self,)).start()
except socket.error as e:
print(f'Failed to connect to chat server @ port {self.port}')
sys.exit(1)
def cleanup(self):
"""Close the connection and wait for the thread to terminate."""
self.sock.close()
def run(self):
""" Chat client main loop """
while self.connected:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin and socket
# readable, writeable, exceptional = select.select([0, self.sock], [], [])
readable, writeable, exceptional = select.select(
[self.sock], [], [])
for sock in readable:
# if sock == 0:
# data = sys.stdin.readline().strip()
# if data:
# send(self.sock, data)
if sock == self.sock:
data = receive(self.sock)
if not data:
print('Client shutting down.')
self.connected = False
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print(" Client interrupted. " "")
stop_thread = True
self.cleanup()
break
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--name', action="store", dest="name", required=True)
parser.add_argument('--port', action="store",
dest="port", type=int, required=True)
given_args = parser.parse_args()
port = given_args.port
name = given_args.name
client = ChatClient(name=name, port=port)
client.run()