No attribute to append socket python - python

I'm creating a simple chat server and when I try to connect a client I get this error:
Traceback (most recent call last):
File "C:\Users\OneDrive\Desktop\Py Files\chat_server.py", line 47, in <module>
recive()
File "C:\Users\OneDrive\Desktop\Py Files\chat_server.py", line 39, in recive
client.append(client)
AttributeError: 'socket' object has no attribute 'append'
Here is my code:
import threading
import socket
host = '127.0.0.1'
port = 20200
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen()
clients = []
nicknames = []
def brodcast(message):
for client in clients:
client.send(message)
def handle(client):
while True:
try:
message = client.recv(1024)
brodcast(message)
except:
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
brodcast(f'{nickname} left the chat'.encode('ascii'))
nicknames.remove(nickname)
break
def recive():
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
client.send('NICK'.encode('ascii'))
nickname = client.recv(1024).decode('ascii')
nicknames.append(nickname)
client.append(client)
print(f'{nickname} joined the chat!')
brodcast(f'{nickname} joined the chat!')
client.send('Connected to the chat')
thread = threading.Thread(target=handle, args=(client,))
thread.start()
recive()
I've provided the code for the server because that is where the error is. On the client end, there appears to be no issues.

Related

(Python) Socket Chat returning usernames as IP and Port

I'm working on a TCP socket chat assignment for school. I'm having trouble getting the last part done, which is returning all usernames to the client when it asks for it. The client can write /users to get all connected users usernames, but instead gets the IP and PORT they are connected to, output example:
('127.0.0.1', 54612)
Server Code:
import socket, threading
clients = []
nicknames = []
BYTES = 1024
FORMAT = "utf-8"
def server():
IP = "127.0.0.1"
PORT = 9090
BIND = (IP, PORT)
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(BIND)
sock.listen()
print("Welcome to Budget-Discord!")
while True:
client, addr = sock.accept()
print("Connected with {}".format(str(addr)))
client.send('NICKNAME'.encode(FORMAT))
nickname = client.recv(BYTES).decode()
nicknames.append(nickname)
clients.append(client)
print("Nickname is {}".format(nickname))
print(nicknames)
#broadcast("{} joined!".format(nickname).encode(FORMAT))
client.send("\t >>> Connected to server!".encode(FORMAT))
threading.Thread(target=user_conn, args=[client, addr]).start()
except Exception as e:
print(f"Error, socket: {e}")
def sendall(msg: str, conn: socket.socket): # Broadcast
for client_conn in clients:
if client_conn != conn:
try:
client_conn.send(msg.encode())
except Exception as e:
print(f"Error, sendall: {e}")
byeee(client_conn)
def user_conn(conn: socket.socket, nicknames):
while True:
try:
msg = conn.recv(BYTES).decode()
if "/users" in msg:
conn.sendall(bytearray(str(nicknames).encode()))
if msg:
print(msg)
allchat = f"{msg}"
sendall(allchat, conn)
# else:
# pass
except Exception as e:
print(f"Error, user connection: {e}")
byeee(conn)
break
def byeee(conn: socket.socket):
if conn in clients:
conn.close()
clients.remove(conn)
if __name__ == "__main__":
server()
Client Code:
import socket, threading
IP = "127.0.0.1"
PORT = 9090
BIND = (IP, PORT)
BYTES = 1024
FORMAT = "utf-8"
nickname = input("Choose your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(BIND)
def receive():
while True:
try:
msg = client.recv(BYTES).decode()
if msg == 'NICKNAME':
client.send(nickname.encode())
# elif message == "/users"
else:
print(msg)
except Exception as e:
print(f"Error, client receive: {e}")
client.close()
break
def write():
while True:
msg = f"{nickname}: {input('')}"
client.send(msg.encode())
receive_t = threading.Thread(target=receive).start()
write_t = threading.Thread(target=write).start()
I have tried different things, got tuple errors for the most part so I converted the /users in the server module to bytearray...
In the function server, this line is sending addr as the second argument:
threading.Thread(target=user_conn, args=[client, addr]).start()
but the function user_conn has a second argument of nicknames:
def user_conn(conn: socket.socket, nicknames):
so send nicknames instead in server:
threading.Thread(target=user_conn, args=[client, nicknames]).start()

Got too many errors in server chat.py in python

It seems i have 2 errors, 1st is that cannot concatenate str and bytes, 2nd is that that the connection was closed by the remote host. Wanna help.
I want that this sends a message to all the clients that this person has left the chat, instead of that it is giving the 2nd answer.
Server_chat.py
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
def accept_incoming_connections():
"""Sets up handling for incoming clients."""
while True:
client, client_address = SERVER.accept()
print("%s:%s has connected." % client_address)
client.send(bytes("Greetings from the cave! Now type your name and press enter!", "utf8"))
addresses[client] = client_address
Thread(target=handle_client, args=(client,)).start()
def handle_client(client): # Takes client socket as argument.
"""Handles a single client connection."""
name = client.recv(BUFSIZ).decode("utf8")
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
client.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat!" % name
broadcast(bytes(msg, "utf8"))
clients[client] = name
while True:
msg = client.recv(BUFSIZ).decode('utf8')
if msg != bytes("{quit}", "utf8"):
broadcast(msg, name+": ")
else:
client.send(bytes("{quit}", "utf8"))
client.close()
del clients[client]
broadcast(bytes("%s has left the chat." % name, "utf8"))
break
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
clients = {}
addresses = {}
HOST = '127.0.0.1'
PORT = 33000
BUFSIZ = 1024
ADDR = (HOST, PORT)
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)
if __name__ == "__main__":
SERVER.listen(5)
print("Waiting for connection...")
ACCEPT_THREAD = Thread(target=accept_incoming_connections)
ACCEPT_THREAD.start()
ACCEPT_THREAD.join()
SERVER.close()
client_chat.py
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread
import tkinter
def receive():
"""Handles receiving of messages."""
while True:
try:
msg = client_socket.recv(BUFSIZ).decode("utf8")
msg_list.insert(tkinter.END, msg)
except OSError: # Possibly client has left the chat.
break
def send(event=None): # event is passed by binders.
"""Handles sending of messages."""
msg = my_msg.get()
my_msg.set("") # Clears input field.
client_socket.send(bytes(msg, "utf8"))
if msg == "{quit}":
client_socket.close()
top.quit()
def on_closing(event=None):
"""This function is to be called when the window is closed."""
my_msg.set("{quit}")
send()
top = tkinter.Tk()
top.title("Chatter")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar() # For the messages to be sent.
my_msg.set("Type your messages here.")
scrollbar = tkinter.Scrollbar(messages_frame) # To navigate through past messages.
# Following will contain the messages.
msg_list = tkinter.Listbox(messages_frame, height=15, width=50, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
#----Now comes the sockets part----
HOST = '127.0.0.1'
PORT = 33000
if not PORT:
PORT = 33000
else:
PORT = int(PORT)
BUFSIZ = 1024
ADDR = (HOST, PORT)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
tkinter.mainloop()
Error
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:43:08) [MSC v.1926 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>>
== RESTART: C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py ==
Waiting for connection...
127.0.0.1:59150 has connected.
127.0.0.1:59176 has connected.
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 28, in handle_client
broadcast(msg, name+": ")
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 40, in broadcast
sock.send(bytes(prefix, "utf8")+msg)
TypeError: can't concat str to bytes
Exception in thread Thread-3:
Traceback (most recent call last):
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\arun.kumar2\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\arun.kumar2\Documents\python\chatting app\server_chat.py", line 26, in handle_client
msg = client.recv(BUFSIZ).decode('utf8')
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
Error is at server_chat.py at line 40
You can't contact string with bytes type so you have to keep them both same type or chnage type of one of them.
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix+msg, "utf8"))
As the first error said, you cannot concat str (msg) and bytes, so use:
sock.send(bytes(prefix+msg, "utf8"))
Also you should not call bytes(...) on the argument of broadcast() like below:
broadcast(bytes(msg, "utf8"))
Since you have called bytes(...) inside broadcast(). Use below instead:
broadcast(msg)
For the second error, it is because the connection to client is lost but the server is still trying to read from client. You should use try/except to catch the connection lost.
Below is the modified handle_client() and broadcast():
def handle_client(client): # Takes client socket as argument.
"""Handles a single client connection."""
name = client.recv(BUFSIZ).decode("utf8")
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
client.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat!" % name
broadcast(msg) ###
clients[client] = name
while True:
try:
msg = client.recv(BUFSIZ).decode('utf8')
if msg != "{quit}": ###
broadcast(msg, name+": ")
else:
client.send(bytes("{quit}", "utf8"))
break
except (ConnectionResetError, ConnectionAbortedError):
break
client.close()
del clients[client]
broadcast("%s has left the chat." % name) ###
print(name, "disconnected")
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix+msg, "utf8"))

lately, I am try to build a client and server to send and receive message and I am stuck

I am just trying to build a basic chat with one client and server. When I run both program they both gave me same error. This error is of client1.py
Traceback (most recent call last):
File "C:/Users/Abishek/AppData/Roaming/JetBrains/PyCharmCE2020.2/scratches/client1.py", line 1, in <module>
from socket import socket, AF_INET, SOCK_STREAM
File "C:\Users\Abishek\AppData\Roaming\JetBrains\PyCharmCE2020.2\scratches\socket.py", line 64, in <module>
IntEnum._convert_(
File "C:\Python37\Lib\enum.py", line 349, in __getattr__
raise AttributeError(name) from None
AttributeError: _convert_
and chatserver.py throw an error as:
Traceback (most recent call last):
File "C:/Users/Abishek/AppData/Roaming/JetBrains/PyCharmCE2020.2/scratches/chatserver.py", line 1, in <module>
from socket import AF_INET,SOCK_STREAM, socket
File "C:\Users\Abishek\AppData\Roaming\JetBrains\PyCharmCE2020.2\scratches\socket.py", line 64, in <module>
IntEnum._convert_(
File "C:\Python37\Lib\enum.py", line 349, in __getattr__
raise AttributeError(name) from None
AttributeError: _convert_
and my code for client1.py is
from socket import socket, AF_INET, SOCK_STREAM
import threading
FORMAT = 'utf-8'
server =input('Enter server ip :')
port = 8080
DISCONNECT_MSG = 'break' or 'disconnect'
sock = socket(AF_INET,SOCK_STREAM)
def connection(server,port):
try:
sock.connect((server, port))
print("Connection successful")
except Exception as err:
print('Connection failed :' +str(err))
def send_msg(client_name):
connected = True
while connected:
message = input('>>> ')
msg = message.encode(FORMAT)
client_info_with_msg = f'[{client_name}: {message}]'
sock.send(client_info_with_msg.encode())
if message == DISCONNECT_MSG:
print(f'{client_name} DISCONNECTED!!')
connected = False
def recv_msg():
run = True
while run:
recv_message = sock.recv(512)
message = recv_message.decode('utf-8')
if message == DISCONNECT_MSG:
run = False
print(f'{message}')
def main(server,port):
connection(server, port)
client_name = input("Enter your name: ")
thread1 = threading.Thread(target=send_msg, args=client_name)
thread1.start()
thread2 = threading.Thread(target=recv_msg, args=None)
thread2.start()
thread1.join()
thread2.join()
sock.close()
main(server,port)
And chatserver.py is:
from socket import AF_INET,SOCK_STREAM, socket
import threading
SERVER = socket.gethostbyname(socket.gethostname())
port = 4444
sock = socket.socket(AF_INET,SOCK_STREAM)
format = 'utf-8'
buffer_size = 128
ADDR = (SERVER,port)
Disconnect_msg = 'Disconnected'
def connection(SERVER,port):
sock.bind(ADDR)
run = True
try:
sock.connect(ADDR)
print('Connection successful')
except Exception as err:
print('Error connecting to client :'+str(err))
run = False
def receiving_data(conn, addr):
connected = True
while connected:
recv_msg = conn.recv(buffer_size).decode(format)
if recv_msg:
print(f"[MESSAGE RECEIVED FROM {conn} {addr}] : {recv_msg}")
if Disconnect_msg in recv_msg:
print(f"[CLIENT {conn} { addr} Disconnected]")
connected= False
if __name__ == '__main__':
sock.bind(ADDR)
sock.listen(5)
print(f'Server ip; {SERVER}')
print('Waiting for connection...')
conn , addr = sock.accept()
accpt_conn = threading.Thread(target=connection, args=ADDR)
recv_data = threading.Thread(target=receiving_data, args =(conn,addr))
recv_data.start()
accpt_conn.start()
recv_data.join()
accpt_conn.join()
sock.close()
Can you please help me what I am doing wrong here.
And I am using Pycharm as my IDE and I am on windows 10.
Thank you everyone...

Problem with pickle.loads() - ran out of input

I'm trying to make a small multiplayer game and thus need to send objects. Have created server and client and everything is working for sending bytes e.g. (str("").encode(utf-8)).
But when I tried to use pickle I've started bumping into issues. Have I made any mistakes below?
Server.py:
import socket
import threading
import pickle
HEADER = 8 #Contains info about incoming msg SIZE! first 8 bytes contains size
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(ADDR)
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = pickle.loads(client_socket.recv(2048))
print(f"[RECEIVED] {client_addr} - {msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
def start_server(server):
server.listen()
print("[STARTED] server is online!")
while True:
client_socket, client_addr = server.accept()
thread = threading.Thread(target=handle_client, args=(client_socket, client_addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start_server(server_socket)
Client.py
import socket
import pickle
HEADER = 8
FORMAT = "utf-8"
PORT = 5558
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
DISCONNECT_MSG = "!Disconnect"
class Client:
def __init__(self):
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def connect_to_server(self, server_address):
"""
:param server_address: tuple(IP, PORT)
:return:
"""
self.get_client_socket().connect(server_address)
def get_client_socket(self):
return self.client_socket
def send_object(self, object):
msg = pickle.dumps(object)
self.get_client_socket().sendall(msg)
client = Client()
client.connect_to_server(ADDR)
d = "1"
client.send_object(d)
#client.send_object(DISCONNECT_MSG)
I've also tried to put while loop into send_object() but then after couple of successful receivements I get:
msg = pickle.loads(client_socket.recv(2048))
_pickle.UnpicklingError: invalid load key, '\x00'.
After some research it appears that before trying to unpickle an object you first need to check if received message is not None. Because server is constantly trying to receive message from client, but that is another issue.
Code modification in server.py:
def handle_client(client_socket, client_addr):
print(f"[NEW CONNECTION] {client_addr} connected!")
while True:
try:
msg = client_socket.recv(2048)
if msg:
new_msg = pickle.loads(msg[HEADER:])
print(f"[RECEIVED] {client_addr} - {new_msg}")
if msg == DISCONNECT_MSG:
print(f"[DISCONNECTED] client {client_addr} has disconnected")
client_socket.close()
return False
except socket.error as e:
print(e)
Note -> Until DISCONNECT message is not sent from client it will use much processor time (issue mentioned above)

IndexError: list index out of range Multi-threaded server

from socket import *
import thread
def thread_handler(connectionSocket, addr):
while True:
# Establish the connection
print ("Ready to serve...")
# connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
# print(message, '::', message.split()[0], ":", message.split()[1])
filename = message.split()[1]
# print(filename, "||", filename[1:])
f = open(filename[1:], "r")
outputdata = f.read()
# print(outputdata)
#Send one HTTP header line into socket
#Fill in start
connectionSocket.send('\nHTTP/1.1 200 OK\n\n')
connectionSocket.send(outputdata)
#Fill in end
#Send the content of the requested file to the client
for i in range(0,len(outputdata)):
connectionSocket.send(outputdata[i:i+1])
connectionSocket.send(b'\r\n\r\n')
except IOError:
#Send response message for file not found
#Fill in Start
connectionSocket.send('\nHTTP/1.1 404 Not Found\n\n')
#Fill in end
#Close client socket
if __name__ == '__main__':
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
serverSocket.bind(("localhost", 6789))
serverSocket.listen(1)
while True:
print('waiting for connection...')
connectionSocket, addr = serverSocket.accept()
print('...connected from:', addr)
thread.start_new_thread(thread_handler, (connectionSocket, addr))
serverSocket.close()
I understand how the multi threading works now, but I could not figure out how to build a connection.
I'm trying to do a multi-threaded version of TCP server. However, it keeps giving "list index out of range":
Ready to serve...
Unhandled exception in thread started by <function thread_handler at 0x10b9750c8>
Traceback (most recent call last):
File "http_server_multi.py", line 16, in thread_handler
filename = message.split()[1]
IndexError: list index out of range
If nothing is received from the socket because there is no data yet, the split() will return [''] with only on item and the [1] on it will fail.
Try to add this before the failing line
if not message:
# time.sleep(0.01)
continue
The sleep() call will prevent the thread to use too much CPU, you can umcomment it and adapt the value to your needs.

Categories