My goal is to take a provided framework python file and add the functionality to make a chat server that handles multiple clients. I have done edits in the chat_output, server, and client functions, and are currently inside the multi-line comments.
First step is to get the client to connect without issues. Then I would need to add a raw_input() call so that a user can type something, send it to the server, and then have the server sendall() to the clients.
import socket
class Stream(object):
" abstract "
def write(self,data):
pass
def read(self):
pass
class TCPStream(Stream):
def __init__(self,the_socket):
self.s = the_socket
self.address = None
def read(self,amount=None):
if amount is None:
return self.s.recv(4096)
else:
return self.s.recv(amount)
def set_address(self,address):
self.address = address
def get_address(self):
return self.address
def write(self,data):
self.s.sendall(data)
def __del__(self):
self.s.close()
def shutdown(self):
self.s.shutdown(socket.SHUT_WR)
class Socket(object):
pass
class TCPBaseSocket(Socket):
def __init__(self,port):
self.s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.port = port
class TCPReceivingSocket(TCPBaseSocket):
def __init__(self,port,address=''):
super().__init__(port)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((address,self.port))
self.s.listen(1)
def connection(self):
sc, sockname = self.s.accept()
result = TCPStream(sc)
result.set_address(sockname)
return result
class TCPSendingSocket(TCPBaseSocket):
def __init__(self,port,address):
super().__init__(port)
self.s.connect((address,port))
self._stream = TCPStream(self.s)
self._stream.set_address((address,port))
def stream(self):
return self._stream
if __name__ == "__main__":
import argparse
import threading
import sys
def chat_input(stream):
"""
Enter your code here, shouldn't need to be more than 10 lines of code
"""
pass
def chat_output(stream):
"""
Enter your code here, shouldn't need to be more than 10 lines of code
#stream = TCPStream(stream)
s = TCPStream(stream)
while True:
data = s.read() #s.recv(4096)
if not data:
print("Disconnected from chat server")
break
#stream.write(data) #sendall(data)
"""
def server(interface,port):
"""
Enter your code here, shouldn't need to be more than 10 lines of code
tsc = TCPReceivingSocket(port, interface)
print("Server is running.....n")
addr = tsc.connection().get_address()
print(addr, " is now connected!n")
"""
pass
server_input_thread = threading.Thread(target = chat_input, args = (tsc,))
server_output_thread = threading.Thread(target = chat_output, args = (tsc,))
server_input_thread.start()
server_output_thread.start()
server_input_thread.join()
server_output_thread.join()
def client(interface,port):
"""
Enter your code here, shouldn't need to be more than 10 lines of code
tsc = TCPSendingSocket(port, interface)
"""
pass
client_input_thread = threading.Thread(target = chat_input, args=(tsc,))
client_output_thread = threading.Thread(target = chat_output, args=(tsc,))
client_input_thread.start()
client_output_thread.start()
client_input_thread.join()
client_output_thread.join()
choices = {'client':client,'server':server}
parser = argparse.ArgumentParser(description='Chat via TCP')
parser.add_argument('role',choices=choices,help="which role to take")
parser.add_argument('host',help='interface the server listens at; host the client sends to')
parser.add_argument('-p',metavar='PORT',type=int,default=1060,help='TCP port (default 1060)')
args = parser.parse_args()
function=choices[args.role]
function(args.host,args.p)
For those who are running this, use the command line:
python3 [filename].py server localhost
python3 [filename].py client localhost
With my code uncommented: The server connects. Once I initiate a client, this shoots an error (abbreviated):
line (21?) in read
return self.s.recv(4096)
AttributeError: 'TCPSendingSocket' object has no attribute 'recv'
and also causes
Exception:
self.s.close()
AttributeError: 'TCPSendingSocket' object has no attribute 'close'
The server then gets the same errors except "TCPReceivingSocket"
Aucun commentaire:
Enregistrer un commentaire