python multiple clients chat doesn't work - python

When i run main and client's py files not showing error but doesn't show the input to send the message. how to fix?
main.py result -- > Waiting... and connected 192.168.1.26 58767
clients.py result -- > nothing
this is main.py
import threading
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host="192.168.1.26"
port=1111
threadcount=0
server.bind((host,port))
print("Waiting...")
server.listen(3)
def clients(connection):
connection.send(str.encode("welcome\n"))
while True:
data=connection.recv(2048)
reply="server says" + data.decode("utf-8")
if not data:
break
connection.sendall(str.encode(reply))
connection.close()
while True:
client,adress=server.accept()
print("connected"+ str(adress[0]) + " " + str(adress[1]))
threading.Thread(target=clients,args=(client,))
threadcount+=1
server.close()
this is clients.py
import socket
client_socket=socket.socket()
host="192.168.1.26"
port=1111
client_socket.connect((host,port))
response=client_socket.recv(1024)
print("hello")
while True:
input=input("say")
client_socket.send(str.encode(input))
Response=client_socket.recv(1024)
print(Response.decode("utf-8"))
client_socket.close()

It looks like your thread is never actually starting. One solution is to define a class that implements your thread logic in a run routine. The class should inherit threading.Thread. Then you can simply initialize the class as an object and call its start routine. Try the following variant of your original server code.
import threading
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host="192.168.1.26"
port=1111
threadcount=0
server.bind((host,port))
print("Waiting...")
server.listen(3)
class ServerThread(threading.Thread):
def __init__(self, threadsocket):
threading.Thread.__init__(self)
self.threadsocket = threadsocket
def run(self):
self.threadsocket.send(str.encode("welcome\n"))
while True:
data=self.threadsocket.recv(2048)
reply="server says" + data.decode("utf-8")
print(reply)
if not data:
break
self.threadsocket.sendall(str.encode(reply))
self.threadsocket.close()
while True:
client,adress=server.accept()
print("connected"+ str(adress[0]) + " " + str(adress[1]))
thread = ServerThread(client)
thread.start()
threadcount+=1
server.close()
As far as the client, as I mentioned in a comment you should not use input as a variable name to store the result of the input function. Change it to something like data instead.

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

i want that client can send private message also from a broadcast server socket python

i have made a broadcast server and client both and i have used a message as command like #private to work as a command and and that will list all users and then i want that it should select one of them and then it can only chat with those client only which he as selected and on the backend broadcast also work for others
server()
# import socket programming library
import socket
import time
# import thread module
from _thread import *
import threading
def chatwithtwo(c,username,numusr,data):
c.send("choose to which one you wanna chat".encode())
for i in range(len(username)):
select=f"{i}. {username[i]}\n"
c.send(select.encode())
#here the thread gives problem
select_username=c.recv(1024)
print("select:",select_username.decode())
try:
if username[int(select_username)] in username:
chat_two_display(numusr,c,clients[int(select_username)])
else:
c.send("wrong selection".encode())
except:
c.send("wrong input".encode())
lock.release()
def chat_two_display(numusr,c,recver):
sendcheck={}
while True:
data = c.recv(1024)
sendcheck[numusr]=c
for i in range(len(clients)):
if clients[i]==recver:
send_to=usernames[i]
print(f"[+] {numusr} --> {send_to}:- {data.decode()}")
chat_two_send(numusr,data.decode(),recver)
def chat_two_send(numusr,data,recver):
sendingtoall=f"[+] {numusr} (private):- {data}"
recver.send(sendingtoall.encode())
def send_data(numusr,senddata,clients,sendcheck):
lock.release()
for i in range(len(clients)):
if not clients[i]==sendcheck[numusr]:
sendingtoall=f"[+] {numusr}:- {senddata}"
clients[i].sendall(sendingtoall.encode())
def display_data(c,numusr):
global lock
lock=threading.Lock()
sendcheck={}
while True:
time.sleep(0.5)
data = c.recv(1024)
sendcheck[numusr]=c
print(f"[+] {numusr}:- {data.decode()}")
lock.acquire()
if data.decode()=="#private":
#thread.acquire()
chatwithtwo(c,usernames,numusr,data)
else:
send_data(numusr,data.decode(),clients,sendcheck)
# thread function
def threaded(clients,username):
for i in range(len(clients)):
threading.Thread(target=display_data,args=(clients[i],username[i])).start()
def username_check(c):
while True:
uname=c.recv(1024)
if uname.decode() not in usernames:
datatosend=f"your username is {uname.decode()}"
usernames.append(uname.decode())
clients.append(c)
c.sendall(datatosend.encode())
break
else:
c.send("[-] This username is alredy in use!!!".encode())
def Main():
host = "127.0.0.1"
# reserve a port on your computer
# in our case it is 12345 but it
# can be anything
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("socket binded to port", port)
# put the socket into listening mode
s.listen(5)
print("socket is listening")
global clients
global usernames
global threads
clients=[]
usernames=[]
threads=[]
connectio(s)
def connectio(s):
while True:
# establish connection with client
c, addr = s.accept()
# lock acquired by client
print('Connected to :', addr[0], ':', addr[1])
username_check(c)
# Start a new thread and return its identifier
threaded(clients,usernames)
if __name__ == '__main__':
Main()
client()
import socket
import threading
import time
def send_data(s):
while True:
message=input("")
s.send(message.encode('ascii'))
time.sleep(0.5)
if message=="close":
s.close()
def display_data(s):
while True:
data = s.recv(1024)
print(str(data.decode('ascii')))
time.sleep(0.5)
def Main():
# local host IP '127.0.0.1'
host = '127.0.0.1'
# Define the port on which you want to connect
port = 8000
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# connect to server on local computer
s.connect((host,port))
while True:
username=input("enter your username which should be unique:-")
s.send(username.encode())
username_check=s.recv(1024)
print(username_check.decode())
if username_check:
if username_check.decode()!="Try again":
break
# message you send to server
threading.Thread(target=send_data,args=(s,)).start()
threading.Thread(target=display_data,args=(s,)).start()
# close the connection
if __name__ == '__main__':
Main()
i have called a function for it that is chatwithtwo() but the problem is when select_username variable is receiving the value other threads also work at the same time all that get messed up please help me out in that
Just remove your for i in range(len(clients)): this from threaded function and all done
it will run your thread every time a client will connect to the server like if one client is connected then it will run for 1 time threads=1 running then the second time will run then its value will be 2 and the loop will run twice and the thread value fill get added to the last one like now running thread is 1 and after loop 2 more will be added and now threads are 3 and so on.

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.

When combine TCPServer with ThreadingMixIn, it block

the server-side code (tcp_server.py):
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
class Server(ThreadingMixIn, TCPServer):
pass
class Handler(StreamRequestHandler):
def handle(self):
print 'got a connection from: ', self.request.getpeername()
print self.rfile.read(1024)
msg = 'hello'
self.wfile.write(msg)
server = Server(('127.0.0.1', 8888), Handler)
server.serve_forever()
the client-side code (tcp_client.py):
from socket import *
import threading
def do_connection():
s = socket(AF_INET, SOCK_STREAM)
s.connect(('127.0.0.1', 8888))
s.sendall('this is client')
print s.recv(1024)
ts = []
for x in xrange(100):
print x
t = threading.Thread(target=do_connection())
t.daemon = True
ts.append(t)
for t in ts:
t.start()
I runned tcp_server.py, and then tcp_client.py. tcp_client.py should have been over soon. However, tcp_client.py seemed just run only one thread and blocked, and tcp_server.py got only one connection. When I interrupted tcp_client.py,tcp_server.py got one message this is client。
Is there any mistake in my code ?
This line:
t = threading.Thread(target=do_connection())
Should be
t = threading.Thread(target=do_connection)
When you use do_connection(), you end up executing do_connection in the main thread, and then pass the return value of that call to the Thread object. What you want to do is pass the do_connection function object to Thread, so that the Thread object can execute do_connection in a new thread when you call t.start.
Also, note that starting 100 threads concurrently to connect to your server may not perform very well. You may want to consider starting with fewer threads, and working your way up to a higher number once you know things are working properly.
because the server is blocked by the first request, I try to change the read(1024) to
readline in the server.py and add a '\n' to the content sended from the client, it
works.
it seems the rfile.read(1024) will block the how process, so the goodway is use readline
or use the self.request.recv(1024)
server.py
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
class Server(ThreadingMixIn, TCPServer):
pass
class Handler(StreamRequestHandler):
def handle(self):
print 'got a connection from: ', self.request.getpeername()
print self.rfile.readline()
#print self.request.recv(1024).strip()
msg = 'hello'
self.wfile.write(msg)
# Create the server, binding to localhost on port 9999
server = Server(("127.0.0.1", 8888), Handler)
server.serve_forever()
client.py
from socket import *
import threading
def do_connection():
print "start"
s = socket(AF_INET, SOCK_STREAM)
s.connect(('127.0.0.1', 8888))
s.sendall('this is client\n')
print s.recv(1024)
ts = []
for x in xrange(100):
print x
t = threading.Thread(target=do_connection)
ts.append(t)
for t in ts:
print "start t"
t.start()

Threading - How to recieve and reply at the same time using the socket module?

I am trying to make a simple LAN instant messager where many clients connect to the server and the server replies back and can see what the client is saying. I have tried but my lack of knowledge using the threading module has limited me. At the moment, however, the server only gets a message and has to reply to get the next one. I am trying to make it so the server can see all the messages it receives instantly and can reply whenever he need to. How?
Server Code:
from threading import *
import socket
s = socket.socket()
host = socket.gethostbyname(socket.gethostname())
port = 1337
s.bind((host, port))
s.listen(5)
def getMainThread():
for thread in enumerate(): # Imported from threading
if thread.name == 'MainThread':
return thread
if thread.name == 'Thread':
return thread
return None
class client(Thread):
def __init__(self, socket, address):
Thread.__init__(self)
self.socket = socket
self.address = address
self.start() # Initated the thread, this calls run()
def reply(self):
reply = getThread()
while reply and reply.isAlive():
sent = input("Enter Message: ")
self.socket.send(bytes(sent, 'UTF-8'))
def run(self):
main = getMainThread()
while main and main.isAlive():
message = self.socket.recv(8192).decode('utf-8')
self.socket.send(b"Got your message.. send another one!")
print('Someone:',message)
sent = input("Enter Message: ")
self.socket.send(bytes(sent, 'UTF-8'))
self.socket.close()
while True:
c, addr = s.accept()
client(c, addr)
Client Code:
import socket
host = socket.gethostbyname(socket.gethostname())
print("""
================================================================================
Welcome to Coder77's local internet message for avoiding surveillance by the NSA
================================================================================
The current soon to be encrypted server is {0}
""".format(host))
#host = input("Please select the IP you would like to communicate to: ")
print("Now connecting to {0}....".format(host))
sock = socket.socket()
try:
sock.connect((host, 1337))
while True:
message = input("Enter Message: ")
if message == 'quit':
break
sock.send(bytes(message, 'UTF-8'))
recieved = sock.recv(8192).decode('utf-8')
print('Server responded with:', recieved)
except socket.error:
print ("Host is unreachable")
sock.close()
Also, is it possible using Threading so that 2 while statements can run at the same time? If so, can someone give me an example?
Boosting this to try and get an answer. Anyone?

Categories

Resources