program only running a thread once while using sockets in python - python

i have this server code:
import socket
import threading
host = "host"
port = 55555
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_list = []
color_list = []
server.bind((host, port))
server.listen()
def broadcast(message):
for client in client_list:
client.send(message.encode("ascii"))
def accept_conn():
while True:
conn, addr = server.accept()
if conn not in client_list:
client_list.append(conn)
conn.send("color".encode("ascii"))
color = conn.recv(1024).decode("ascii")
color_list.append(color)
message = conn.recv(1024).decode("ascii")
color_1 = color_list[client_list.index(conn)]
broadcast("[SERVER]recieved")
print(f"SERVER {host} RUNNING")
thread = threading.Thread(target=accept_conn)
thread.start()
and this client code:
import socket
import threading
host = "host"
port = 55555
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
color = input("enter the color: ")
def write():
while True:
message = input("")
client.send(message.encode("ascii"))
def recieve():
check = 1
while True:
message = client.recv(1024).decode("ascii")
if message == "color" and check == 1:
client.send(color.encode("ascii"))
check = 0
else:
print(message)
thread = threading.Thread(target=write)
thread2 = threading.Thread(target=recieve)
thread.start()
thread2.start()
now what this is supposed to do is recieve messages from the client and in response send to all connected clients the message recieved from the client.
right now im checking if it sends it to all clients by sending "recieved" from the server the client after every time the server recieves a message from the client.
the output looks like this:
enter the color: red
hi
[SERVER]recieved
im
the problem with this is that when i write the first message the server responds with "recieved" but after that it dosent which seems to me like its only running once.
would like some help on this.

Related

Server not receiving messages from client

Hi This is my first post here. I am making a chatroom in Python using sockets and I have written the code for the server and client side. I am successful in establishing a connection between the server and the clients but I can't send any messages. The client provides a password and username through terminal and the server check if the password is correct and only then the client can send messages. I have not yet implemented the password check yet but the messages are still not being sent. I have made sure I am encoding and decoding correctly. I have also implemented threading to allow multiple users. Here is the server side code:
import socket
import threading
import sys
#TODO: Implement all code for your server here
#usernames = []
def broadcast(message):
for client in clients:
client.send(message)
def handle_client(client_socket, client_address):
try:
password = client_socket.recv(1024).decode()
username = client_socket.recv(1024).decode()
print("user: " + username)
clients.append(client_socket)
while True:
message = username + " joined the chatroom"
print(message)
broadcast(message.encode())
message = client_socket.recv(1024).decode()
if (message != ":Exit"):
print(f"{username}: {message}")
broadcast(message.encode())
else:
print(f"{username} left the chatroom")
clients.remove(client_socket)
client_socket.close()
message = username + " left the chatroom"
broadcast(message.encode())
break
except:
client_socket.close()
def receive():
while True:
client_socket, client_address = server.accept()
print(client_socket)
client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
client_thread.start()
# Use sys.stdout.flush() after print statemtents
if __name__ == "__main__":
HOST = '127.0.0.1'
#PORT = int(sys.argv[1])
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, 10001))
server.listen(5)
clients = []
print("server is listening")
receive()
Here is the client side:
import socket
import threading
import sys
#TODO: Implement a client that connects to your server to chat with other clients here
HOST = '127.0.0.1'
#PORT = int(sys.argv[1])
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, 10001))
username = sys.argv[1]
password = sys.argv[2]
client_socket.send(password.encode())
client_socket.send(username.encode())
reply = client_socket.recv(1024).decode()
print(reply)
def receive():
while True:
try:
message = client_socket.recv(1024).decode()
if message:
print(message)
except:
continue
def write():
while True:
message = input()
if message == ":Exit":
client_socket.send(message.encode())
client_socket.close()
break
else:
client_socket.send(message.encode())
receive_thread = threading.Thread(target=receive)
receive_thread.start()
write_thread = threading.Thread(target=write)
write_thread.start()
# Use sys.stdout.flush() after print statemtents
if __name__ == "__main__":
pass
I have tried asking my TAs but they were of no help :(.
It looks like you are taking the second and third arguments instead of first and second. Thus if you do not pass 3 arguments with the third being the password then the client will not have a password to send.

How to send a chatlog of all written chats to a newly joined client using socket programming in Python?

I have written a simple server and client py using UDP. The base is working, however I want that every time a user (client) joins, he would receive a chatlog of everything that has been said.
This is my code until now:
Server:
import socket
import threading
import queue
import pickle
messages = queue.Queue()
clients = []
# AF_INET used for IPv4
# SOCK_DGRAM used for UDP protocol
ip = "localhost"
port = 5555
chatlog=[]
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# binding IP and port
UDPServerSocket.bind((ip, port))
def receive():
while True:
try:
message, addr = UDPServerSocket.recvfrom(1024)
messages.put((message, addr))
chatlog.append((message,addr))
except:
pass
def broadcast():
while True:
while not messages.empty():
message, addr = messages.get()
print(message.decode())
if addr not in clients:
clients.append(addr)
for client in clients:
try:
if message.decode().startswith("SIGNUP_TAG:"):
name = message.decode()[message.decode().index(":") + 1:]
UDPServerSocket.sendto(f"{name} joined!".encode(), client)
if len(chatlog)>0:
sending= pickle.dumps(chatlog)
UDPServerSocket.sendto(sending, client)
else:
pass
else:
UDPServerSocket.sendto(message, client)
except:
clients.remove(client)
t1 = threading.Thread(target=receive)
t2 = threading.Thread(target=broadcast)
t1.start()
t2.start()
And the client
import socket
import threading
import random
client= socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.bind(("localhost", random.randint(7000, 8000))) # random port for every client
name = "Henk" #test name
def receive():
while True:
try:
message, _ = client.recvfrom(1024)
print(message.decode())
except:
pass
t= threading.Thread(target= receive)
t.start()
#this gives the server the name of the people who have entered the server
client.sendto(f"SIGNUP_TAG: {name}".encode(), ("localhost", 5555))
while True:
message= input("")
if message=="!q":
exit()
else:
client.sendto(f'[{name}]: {message}'.encode(), ("localhost",5555))
So I am actually a bit stuck on how I will approach this. Shall create a text file where every time that a message is written it gets written on the file as well? Or shall I create some kind of string list/database where every message is stored :/

Python socket problem-ConnectionRefusedError: [WinError 10061]

I wanted to create a server-client chatbox room in python, where multiple clients could send messages in the chat box.
This is the server code
import threading
import socket
#setting up the local host and the local port
host = '127.0.0.1'
port = 9879
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port)) #hosting the server to the host
server.listen() #server listen to incoming connection
#list for client and their nicknames
clients = []
nicknames = []
#broadcast method to send message to all the clients connected to the server
def broadcast(message):
for client in clients:
client.send(message)
def handle (client):
while True:
try:
message = client.recv(1024)
broadcast(message)
except: #if the connection is lost, discard the client
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
broadcast(f'{nickname} already left the chat!'.encode('ascii'))
nicknames.remove(nickname)
break
#function to receive connection
def receive():
while True:
client, address = server.accept()
print(f"Conncected with {str(address)}")
client.send('NICKNAME'.encode('ascii'))
nickname = client.recv(1024).decode('ascii')
nicknames.append(nickname)
clients.append(client)
print(f'The nickname of the client is {nickname}')
broadcast(f'{nickname} joined the chat!'.encode('ascii'))
client.send('Connected to the server!'.encode('ascii'))
#making thread for every client
thread = threading.Thread(target = handle, args = (client,))
thread.start()
print("Server is waiting for client...")
and this is the client code
import socket
import threading
#nickname prompt
nickname = input("Input your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#binding the client to the port
client.connect(('127.0.0.1', 9879))
def receive():
while True:
try:
message = client.recv(1024).decode('ascii')
if message == 'NICKNAME':
client.send(nickname.encode('ascii'))
else:
print(message)
except:
print("An error occurred!")
client.close()
break
def write():
while True:
message = f'{nickname}: {input("")}'
client.send(message.encode('ascii'))
#making the thread
receive_thread = threading.Thread(target = receive)
receive_thread.start()
write_thread = threading.Thread(target = write)
write_thread.start()
However, whenever i inputted the nickname in the command prompt there was an error
Traceback (most recent call last):
File "C:\Users\march\Documents\Programming\Pyhton\client.py", line 8, in <module>
client.connect(('127.0.0.1', 9879))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
I wonder what's the problem because the port for both server and client are the same and the port is available.
On your server code you're missing a call to the receive function that runs the while loop and puts the server on accept for connections.
The code becomes
import threading
import socket
#setting up the local host and the local port
host = '127.0.0.1'
port = 9879
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port)) #hosting the server to the host
server.listen() #server listen to incoming connection
#list for client and their nicknames
clients = []
nicknames = []
#broadcast method to send message to all the clients connected to the server
def broadcast(message):
for client in clients:
client.send(message)
def handle (client):
while True:
try:
message = client.recv(1024)
broadcast(message)
except: #if the connection is lost, discard the client
index = clients.index(client)
clients.remove(client)
client.close()
nickname = nicknames[index]
broadcast(f'{nickname} already left the chat!'.encode('ascii'))
nicknames.remove(nickname)
break
#function to receive connection
def receive():
while True:
client, address = server.accept()
print(f"Conncected with {str(address)}")
client.send('NICKNAME'.encode('ascii'))
nickname = client.recv(1024).decode('ascii')
nicknames.append(nickname)
clients.append(client)
print(f'The nickname of the client is {nickname}')
broadcast(f'{nickname} joined the chat!'.encode('ascii'))
client.send('Connected to the server!'.encode('ascii'))
#making thread for every client
thread = threading.Thread(target = handle, args = (client,))
thread.start()
print("Server is waiting for client...")
receive() # runs the function that accepts for incoming connections
The client code should run the write() function on the main thread and not on another one, because it requires input from the stdin. You can change your code as follows in order to run the receiving routine on another thread and your "writing" function on the main one.
import socket
import threading
#nickname prompt
nickname = input("Input your nickname: ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#binding the client to the port
client.connect(('127.0.0.1', 9879))
def receive():
while True:
try:
message = client.recv(1024).decode('ascii')
if message == 'NICKNAME':
client.send(nickname.encode('ascii'))
else:
print(message)
except:
print("An error occurred!")
client.close()
break
def write():
while True:
message = f'{nickname}: {input("")}'
client.send(message.encode('ascii'))
#making the thread
receive_thread = threading.Thread(target = receive)
receive_thread.start()
# on the main thread
write()
The cause of the Connection refused error was due to the fact that the server code immediately exited since the receive function was never actually called.

Can't tell if python server and client are interacting with each other

Have a client socket here that starts and connects but the receive function never runs or at least doesn't print. I get no errors in the console
import socket
from threading import Thread
MAX_BUFFER_SIZE = 4096
class ClientServer(Thread):
def __init__(self, HOST = "localhost", PORT = 8000):
print("Client Server started w/ new threads...")
Thread.__init__(self)
self.HOST = HOST
self.PORT = PORT
self.socket = None
def receive_from_Server(self):
print('Time to receive from Server.....')
result_bytes = self.socket.recv(MAX_BUFFER_SIZE)
result_string = result_bytes.decode("utf8")
print("Result from server is {}".format(result_string))
def start_server(self):
# Creates TCP socket
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Re-uses socket
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Binds socket to host and port
self.socket.bind(("localhost", 8000))
def connect_server(self):
while True:
threads = []
# Become a server socket
print("Waiting for connections from TCP clients")
self.socket.listen(5)
# Starts connection
(clientSocket, client_address) = self.socket.accept()
newthread = ClientServer()
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
cs = ClientServer()
cs.start_server()
cs.connect_server()
cs.receive_from_Server()
my client code here runs but again print doesn't print after I run this program and enter whatever message besides 'exit' as well as 'exit' not closing the client as well.
import socket
host = "localhost"
port = 8000
BUFFER_SIZE = 4096
MESSAGE = input("Client: Enter message and hit enter or 'exit' to end ")
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((host, port))
while MESSAGE != 'exit':
client.send(MESSAGE.encode("utf8"))
data = client.recv(BUFFER_SIZE)
print("Server received data:" + data)
MESSAGE = input("Client: Enter more or 'exit' to end ")
client.close()

Messaging using Python Socket(Threading)

I was working with Socket and threading library but threading does not work as well as i expected. For e.g. when you send a message from server to client message wont be appear, but i you send a message after that from client to server the message(came from server before) will be appear.
Here is the code for Server side
import socket
from threading import Thread as t
port = 8000
ip = "localhost" # or your ip
s = socket.socket()
s.bind((ip,port))
s.listen()
c, addr = s.accept()
print("Connected")
def se():
while True:
msg = input("Your msg: ")
c.send(msg.encode())
def re():
while True:
msg = c.recv(1024)
print(msg.decode())
t1 = t(target=se)
t2 = t(target=re)
t1.start()
t2.start()
and here is code for client
import socket
from threading import Thread as t
port = 8000
ip = "localhost" # or your ip
s = socket.socket()
s.connect((ip,port))
print("Connected")
def se():
while True:
msg = input("Your msg: ")
s.send(msg.encode())
def re():
while True:
msg = s.recv(1024)
print(msg.decode())
t1 = t(target=se)
t2 = t(target=re)
t1.start()
t2.start()
How can i fix it(i mean i send a message to client and he can see that and when he sends me something i can see that too, with any order and arrangement)

Categories

Resources