Messaging using Python Socket(Threading) - python

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)

Related

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 :/

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()

program only running a thread once while using sockets in 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.

Send Continuous Data to Client from Server python

I am writing a program to send the data continuously to the Client from the Server. In here, i am using a timestamp for sample to send it to the multiple Clients who are connected. I have used multi-threading to support multiple Clients. I want the time to be sent every 10 seconds to the client. but in my code, the client stops after receiving the first data. How to make client continuously receive the data. I tried adding while loop in Client Side but it doesn't make it possible. Any suggestions please
Here's the sample Code:
Server Side:
import socket
import os
from threading import Thread
import thread
import threading
import time
import datetime
def listener(client, address):
print "Accepted connection from: ", address
with clients_lock:
clients.add(client)
try:
while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
with clients_lock:
for c in clients:
c.sendall(data)
finally:
with clients_lock:
clients.remove(client)
client.close()
clients = set()
clients_lock = threading.Lock()
host = socket.gethostname()
port = 10016
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []
while True:
print "Server is listening for connections..."
client, address = s.accept()
timestamp = datetime.datetime.now().strftime("%I:%M:%S %p")
client.send(timestamp)
time.sleep(10)
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
Client Side:
import socket
import os
from threading import Thread
import socket
import time
s = socket.socket()
host = socket.gethostname()
port = 10016
s.connect((host, port))
print (s.recv(1024))
s.close()
# close the connection
My output:
01:15:10
Required Output on clients:
01:15:10
01:15:20
01:15:30
#and should go on
Server side
while True:
client, address = s.accept()
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
In def listener() change while loop to continuously send data for each thread like this
while True:
data = client.recv(1024)
if data == '0':
timestamp = datetime.datetime.now().strftime("%I:%M:%S %p")
client.send(timestamp)
time.sleep(2)
at client side add this line in while loop to send some data to satisfy the if condition
s.connect((host, port))
while True:
s.send('0')
print(s.recv(1024))
#s.close()

Python connecting two clients to a server causes the first client to break

I'm trying to create a simple python chat interface however when two clients are connected to the server, the first clients console prints blank spaces as quick as possible and causes a max recursion depth error while the second client still works fine. The server code only sends data when its not blank so i'm not sure why it does this.
Server code:
import socket
from threading import Thread
from socketserver import ThreadingMixIn
class ClientThread(Thread):
def __init__(self,ip,port):
Thread.__init__(self)
self.ip = ip
self.port = port
print("[+] New thread started for "+ip+": "+str(port))
def run(self):
while True:
data = conn.recv(1024).decode()
if not data: break
if data == "/exit":
print("Connection for "+ip+" closed.")
data = "Connection closed."
conn.send(data.encode())
break
else:
print("received data: ", data)
if data != " ":
conn.send(data.encode())
print("connection "+ip+" force closed.")
TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []
while True:
tcpsock.listen(4)
(conn, (ip,port)) = tcpsock.accept()
newthread = ClientThread(ip,port)
newthread.start()
threads.append(newthread)
for t in threads:
t.join()
Client code:
import socket
import threading
from threading import Thread
TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024
name = str(input("Input username: "))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
def recv():
while True:
data = s.recv(BUFFER_SIZE).decode()
if not data: break
print(data)
recv()
def send():
message = str(input())
if message != "/exit":
message = name + ": " + message
s.send(message.encode())
send()
if __name__ == "__main__":
Thread(target = recv).start()
Thread(target = send).start()
The error is at line 19 in the client code (where its receiving and printing any data sent by the server)
Any help would be greatly appreciated.
The most probable reason is the recursion in your send and receive routines, I changed them to be loops instead.
def recv():
while True:
data = s.recv(BUFFER_SIZE).decode()
if not data: break
print(data)
def send():
while True:
message = str(input())
if message != "/exit":
message = name + ": " + message
s.send(message.encode())
A solution to shutting down these threads is given here: Is there any way to kill a Thread in Python?
But it is not necessary to run send and receive in single threads in this scenario in the clients.
EDIT:
I read again carefully your code. In the client you start the send and receive method as threads. The send thread does not get any input for its message string in the thread and because you loop it, it sends empty messages to the server or (in my case) exits with an error.

Categories

Resources