Reputation: 99
I'm trying to create a message server type of thing. After connecting to the server client-side and attempting to type in a username, it gives the error:
"a bytes-like object is required, not 'str'"
And I wasn't sure If I was mishandling the encoding and decoding functions or not.
import socket, time, sys, threading
class Server:
def __init__(self, port):
while True:
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.port = port
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(('127.0.0.1',port))
self.clients = []
self.usernames = []
print('Successfully bound socket!')
break
except:
print('Error binding, retrying....')
time.sleep(5)
def close(self):
self.socket.close()
def commands(self):
while True:
command = input()
if command.lower() in ['exit', 'end', 'quit', 'q']:
print('Closing Session.....')
server.close(), sys.exit()
def broadcast(self, message):
for client in self.clients:
client.send(message)
def handle(self, client):
while True:
try:
message = client.recv(1024)
server.broadcast(message)
except:
index = self.clients.index(client)
self.clients.remove(client)
client.close()
username = self.usernames[index]
server.broadcast(f'{username.decode("ascii")} has left!')
self.usernames.remove(username)
break
def receive(self, client, addr):
while True:
print(f'New Socket Connection: {addr}')
try:
client.send('USERNAME: '.encode('ascii'))
username = client.recv(1024).decode('ascii')
self.usernames.append(username)
self.clients.append(client)
print(f'Username is: {username}')
server.broadcast(f'{username.encode("ascii")} has connected.')
client.send('Connected to the server!'.encode('ascii'))
thread = threading.Thread(target=handle, args=(client,))
thread.start()
except Exception as e:
print(e)
print('Closed early! (Or wrong values entered!)')
socket.close()
print(f'Client {addr} closed.')
client.send()
def listen(self):
self.socket.listen(5)
print('Listening for new connections....')
while True:
client, addr = self.socket.accept()
client.settimeout(60)
server.receive(client, addr)
server = Server(4545)
try:
server.listen()
except:
server.close()
The problem occurs from the receive function:
def receive(self, client, addr):
while True:
print(f'New Socket Connection: {addr}')
try:
client.send('USERNAME: '.encode('ascii'))
username = client.recv(1024).decode('ascii')
self.usernames.append(username)
self.clients.append(client)
print(f'Username is: {username}')
server.broadcast(f'{username.encode("ascii")} has connected.')
client.send('Connected to the server!'.encode('ascii'))
thread = threading.Thread(target=handle, args=(client,))
thread.start()
except Exception as e:
print(e)
print('Closed early! (Or wrong values entered!)')
socket.close()
print(f'Client {addr} closed.')
client.send()
Upvotes: 1
Views: 2170
Reputation: 863
Have a look at this part of code :
def receive(self, client, addr):
while True:
#[...]
server.broadcast(f'{username.encode("ascii")} has connected.')
You're just encoding the username
but not the complete string!
So it should be something like this :
#[...]
server.broadcast(f'{username} has connected.'.encode("ascii"))
#[...]
Here's the final working code:
import socket, time, sys, threading
class Server:
def __init__(self, port):
while True:
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.port = port
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(('127.0.0.1',port))
self.clients = []
self.usernames = []
print('Successfully bound socket!')
break
except:
print('Error binding, retrying....')
time.sleep(5)
def close(self):
self.socket.close()
def commands(self):
while True:
command = input()
if command.lower() in ['exit', 'end', 'quit', 'q']:
print('Closing Session.....')
server.close(), sys.exit()
def broadcast(self, message):
for client in self.clients:
client.send(message)
def handle(self, client):
while True:
try:
message = client.recv(1024)
server.broadcast(message)
except:
index = self.clients.index(client)
self.clients.remove(client)
client.close()
username = self.usernames[index]
server.broadcast(f'{username.decode("ascii")} has left!')
self.usernames.remove(username)
break
def receive(self, client, addr):
while True:
print(f'New Socket Connection: {addr}')
try:
client.send('USERNAME: '.encode('ascii'))
username = client.recv(1024).decode('ascii')
self.usernames.append(username)
self.clients.append(client)
print(f'Username is: {username}')
server.broadcast(f'{username} has connected.'.encode("ascii"))
client.send('Connected to the server!'.encode('ascii'))
thread = threading.Thread(target=handle, args=(client,))
thread.start()
except Exception as e:
print(e)
print('Closed early! (Or wrong values entered!)')
socket.close()
print(f'Client {addr} closed.')
client.send()
def listen(self):
self.socket.listen(5)
print('Listening for new connections....')
while True:
client, addr = self.socket.accept()
client.settimeout(60)
server.receive(client, addr)
server = Server(4545)
try:
server.listen()
except:
server.close()
Upvotes: 1