Python 3.5: multiple client - server chat - python

At the moment I can send messages to and from clients using the server as a middleman.
However I cannot get the messages that are received by each client to be printed out before a user inputs something. I have come across threading however I am very inexperienced with it.
Server code:
import socket, _thread
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
serversocket.bind((host, port))
serversocket.listen(5)
def send_c2(clientsocket1, clientsocket2):
while True:
msg1 = clientsocket1.recv(1024)
msg1 = msg1.decode('ascii')
clientsocket2.send(msg1.encode('ascii'))
def send_c1(clientsocket1, clientsocket2):
while True:
msg2 = clientsocket2.recv(1024)
msg2 = msg2.decode('ascii')
clientsocket1.send(msg2.encode('ascii'))
while True:
clientsocket1,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
clientsocket2,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
try:
_thread.start_new_thread(send_c2, (clientsocket1, clientsocket2))
_thread.start_new_thread(send_c1, (clientsocket1, clientsocket2))
except:
print("Thread failed")
Client code:
import socket, _thread
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
s.connect((host, port))
def send_msg(r, s):
while True:
msg = input("> ")
s.send(msg.encode('ascii'))
def rec_msg(r, s):
while True:
tm = s.recv(1024)
print(tm.decode('ascii'))
try:
_thread.start_new_thread(send_msg, ("Thread 1", s))
_thread.start_new_thread(rec_msg, ("Thread 2", s))
except:
print("Thread failed")
Is there a way round this?

Related

Sockets Python | chatting server multiple clients

i am trying to implement a TLS secured socket server in python, and i want multiple clients to connect to the server and talk to each other,
what i would like to do is that each client connecting can receive messages sent by other clients also,
Server code:
import socket
import threading
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting ...")
start()
Client Code:
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = "192.168.1.141"
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
send(input('[Send a Message]: '))
send(DISCONNECT_MESSAGE)
where can i add the TLS in this?:/
if something isn't right please inform me :)
---------------------EDIT------------------------------
SERVER:
import socket
import select
HEADER_LENGTH = 10
IP = "127.0.0.1"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen(5)
sockets_list = [server_socket]
clients = {}
def receive_message(client_socket):
try:
message_header = client_socket.recv(HEADER_LENGTH)
if not len(message_header):
return False
message_length = int(message_header.decode('utf-8').strip())
return {"header": message_header, "data": client_socket.recv(message_length)}
except:
return False
while True:
read_sockets, _, exception_sockets = select.select(
sockets_list, [], sockets_list)
for notified_socket in read_sockets:
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
user = receive_message(client_socket)
if user is False:
continue
sockets_list.append(client_socket)
clients[client_socket] = user
print(
f"Accepted new connection from {client_address[0]}:{client_address[1]} username: {user['data'].decode('utf-8')}")
else:
message = receive_message(notified_socket)
if message is False:
print(
f"closed connection from {clients[notified_socket]['data'].decode('utf-8')}")
sockets_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
print(
f"Received message from {user['data'].decode('utf-8')}: {message['data'].decode('utf-8')}")
for client_socket in clients:
if client_socket != notified_socket:
client_socket.send(
user['header'] + user['data'] + message['header'] + message['data'])
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
CLIENT:
from http import client
import socket
import select
import errno
import sys
import threading
HEADER_LENGTH = 10
IP = '127.0.0.1'
PORT = 1234
my_username = input("Username: ")
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
username = my_username.encode('utf-8')
username_header = f"{len(username):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(username_header + username)
def send_message():
message = input(f"{my_username} > ")
if message:
message = message.encode('utf-8')
message_header = f"{len(message):<{HEADER_LENGTH}}".encode('utf-8')
client_socket.send(message_header + message)
while True:
thread = threading.Thread(target=send_message)
thread.start()
try:
while True:
# receive things
username_header = client_socket.recv(HEADER_LENGTH)
if not len(username_header):
print("connection closed by the server")
sys.exit()
username_length = int(username_header.decode('utf-8').strip())
username = client_socket.recv(username_length).decode('utf-8')
message_header = client_socket.recv(HEADER_LENGTH)
message_length = int(message_header.decode('utf-8').strip())
message = client_socket.recv(message_length).decode('utf-8')
print(f"{username} > {message}")
except IOError as e:
if e.errno != errno.EAGAIN and e.errno != errno.EWOULDBLOCK:
print('Reading error', str(e))
sys.exit()
continue
except Exception as e:
print('General error', str(e))
sys.exit()
unfortunately, i cant seem to get the buffer to work right , other clients only receive other clients input when they send messages, so the output is always unordered correctly.

Python socket client doesnt receive anything, hangs by recv.from(datasize)

I have to make a simple udp echo client and server, currently my problem is that the client hangs itself up at the code "data, address = sock.recvfrom(dataSize)". Here is my client and server code (I removed some api functions, so it aint long). I tried same ports and different ports and the same goes with the ip's but i dont get any message back. I tried the original file from a friend and his version works, I have the same port and ip and the same methods on both files, but it still keeps hanging at the echoClient method receiveMSG at the first line.
echoServerUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import json
host = '0.0.0.0'
sport = 11111 # own port
dataSize = 1024
ip_adresses = {}
def echo_server():
receiveSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
receiveSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
receiveSock.bind((host,sport))
print("Starting up echo server on %s port %s" % (host, sport))
while True:
print("Waiting to receive message")
print("Generate a Session ...")
data, address = receiveSock.recvfrom(dataSize)
data = data.decode("utf-8")
if data:
print("receive data: %s from %s" % (data,address))
json_object = json.loads(data)
operation=json_object["operation"]
if operation == "register":
register(json_object["name"],json_object["value"],json_object["sid"])
json_message={"ergebnis":"ok"}
dump = json.dumps(json_message)
sendMSG(bytes(dump,encoding="utf-8"),address)
print("er")
if operation == "unregister":
unregister(json_object["name"],json_object["sid"])
if operation == "query":
query(json_object["sid"])
if operation == "reset":
reset(json_object["sid"])
print("sent %s bytes back to %s" % (data,address))
def sendMSG(data,address):
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sendSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sendSock.sendto(data,address)
sendSock.close()
if __name__ == '__main__':
echo_server()
and here the echoClientUDP.py
0<0# : ^
'''
#echo off
python "%~f0" %*
pause
exit /b 0
'''
#!/usr/bin/env python
import socket
import time
import json
from random import randint
host = '127.0.0.1'
sport = 11111
dataSize = 1024
sid= randint(1,10000)
name=socket.gethostname()
own_ip = socket.gethostbyname(name)
def echo_client():
sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
json_message = {"operation":"register","name":name,"value":own_ip,"sid":sid}
dump = json.dumps(json_message)
print("Sending %s to %s:%s" % (dump,host,sport))
sendMSG(sendSock, dump)
data = receiveMSG(sendSock)
if data:
print("Received: %s" % data)
except Exception as err:
print("Socket error: %s" %str(err))
finally:
print("Closing connection to the server")
sendSock.close()
def sendMSG(sendSock, data):
sendSock.connect((host, sport))
sendSock.sendall(bytes(data,encoding="utf-8"))
def receiveMSG(sock):
data, address = sock.recvfrom(dataSize)
print(data)
return data
if __name__ == '__main__':
echo_client()
Please put more effort in some areas like you have not added any headers and you have gone more complicated i have also created a similar working script see and observe that script and make changes to your script
client.py :-
import socket
import sys
HEADER = 64
PORT = 65432
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
print(client.recv(2048).decode(FORMAT))
def chat():
while True:
try:
a = input()
if 'quit' in a:
sys.exit()
else:
send(a)
except Exception as e:
print(e)
sys.exit()
chat()
server.py :-
import socket
import threading
HEADER = 64
PORT = 65432
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "Bye"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} connected.")
connected = True
while connected:
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] left")
print(f"[{addr}] {msg}")
conn.send("Msg received".encode(FORMAT))
conn.close()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount() - 1}")
print("[STARTING] server is starting...")
start()
and i have used threading here to make the process more fast.
First run the server.py in background and then run client.py to connect to the server.

How to send data to client with conn.send()

Im trying to create a simple chat server. I've been able to send information to the server through the client using 'client.send()' but I cannot seem to do the same server->client
I have tried using methods such as conn.send() and conn.sendall(), but (I guess since the code is in a try) they seem to get skipped after the initial conn.send(str.encode("Connected"))
Server code
import socket
from _thread import *
import sys
server = "192.168.0.4"
port = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for a connection, Server Started")
def threaded_client(conn):
conn.send(str.encode("Connected"))
reply = ""
while True:
conn.send(str.encode(str(reply)))
try:
data = conn.recv(2048*1)
reply = data.decode("utf-8")
if not data:
print("Disconnected")
break
else:
print("Received: ", reply)
print("Sending : ", reply)
conn.sendall(str.encode(reply)) #Where I want to send information to the client
except:
break
print("Lost connection")
conn.close()
while True:
conn, addr = s.accept()
print("Connected to:", addr)
start_new_thread(threaded_client, (conn,))
client code
import socket
class Network:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "192.168.0.4"
self.port = 5555
self.addr = (self.server, self.port)
self.id = self.connect()
print(self.id)
def connect(self):
try:
self.client.connect(self.addr)
return self.client.recv(2048).decode()
except:
pass
def send(self, data):
try:
self.client.send(str.encode(data))
return self.client.recv(2048).decode()
except socket.error as e:
print(e)
from network import Network
n = Network()
while True:
n.send("sending stuff") #this works/sends properly
You forgot to use print() to display data from server
while True:
print( n.send("sending stuff") )
BTW: in server you send the same data two times - with conn.send() and conn.sendall()

Server Loop Using Python Sockets and Threading module

I am making server-client communication in python using sockets and threading module. I connect client to server, send some data, receive some data, but the problem is, I can send only two messages. After those, the server is not reciving my packets. Can someone tell me what's wrong? Thanks in advance.
Server.py:
import socket
from threading import Thread
class Server:
def __init__(self):
self.host = '127.0.0.1'
self.port = 9999
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
self.threads = []
self.listen_for_clients()
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print('Accepted Connection from: '+str(addr[0])+':'+str(addr[1]))
self.threads.append(Thread(target=self.handle_client, args=(client, addr)))
for thread in self.threads:
thread.start()
def handle_client(self, client_socket, address):
client_socket.send('Welcome to server'.encode())
size = 1024
while True:
message = client_socket.recv(size)
if message.decode() == 'q^':
print('Received request for exit from: '+str(address[0])+':'+str(address[1]))
break
else:
print('Received: '+message.decode()+' from: '+str(address[0])+':'+str(address[1]))
client_socket.send('Received request for exit. Deleted from server threads'.encode())
client_socket.close()
if __name__=="__main__":
main = Server()
Client.py
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
while True:
data = input()
client.send(data.encode())
message = client.recv(4096)
print('[+] Received: '+ message.decode())
main()
You have to send exit message 'q^' to client too to close client.
Warning:
Using Unicode as encoding for string is not recommended in socket. A partial Unicode character may be received in server/client resulting in UnicodeDecodeError being raised.
Code for server using threads is:
server.py:
import socket
from threading import Thread
class Server:
def __init__(self, host, port):
self.host = host
self.port = port
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host, self.port))
self.server.listen(5)
def listen_for_clients(self):
print('Listening...')
while True:
client, addr = self.server.accept()
print(
'Accepted Connection from: ' + str(addr[0]) + ':' + str(addr[1])
)
Thread(target=self.handle_client, args=(client, addr)).start()
def handle_client(self, client_socket, address):
size = 1024
while True:
try:
data = client_socket.recv(size)
if 'q^' in data.decode():
print('Received request for exit from: ' + str(
address[0]) + ':' + str(address[1]))
break
else:
# send getting after receiving from client
client_socket.sendall('Welcome to server'.encode())
print('Received: ' + data.decode() + ' from: ' + str(
address[0]) + ':' + str(address[1]))
except socket.error:
client_socket.close()
return False
client_socket.sendall(
'Received request for exit. Deleted from server threads'.encode()
)
# send quit message to client too
client_socket.sendall(
'q^'.encode()
)
client_socket.close()
if __name__ == "__main__":
host = '127.0.0.1'
port = 9999
main = Server(host, port)
# start listening for clients
main.listen_for_clients()
client.py:
import socket
import sys, time
def main():
target_host = '127.0.0.1'
target_port = 9999
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Could not create a socket')
time.sleep(1)
sys.exit()
try:
client.connect((target_host, target_port))
except socket.error:
print('Could not connect to server')
time.sleep(1)
sys.exit()
online = True
while online:
data = input()
client.sendall(data.encode())
while True:
message = client.recv(4096)
if 'q^' in message.decode():
client.close()
online = False
break
print('[+] Received: ' + message.decode())
break # stop receiving
# start client
main()

Python sockets - send variable back to client from server

I am using sockets for a client / server application, where I need to send a variable from the server back to the client when the use clicks a button, for example. I am using wxpython.
Here is a sample of my server code:
def handler(self, clientsocket, clientaddr):
data22 = clientsocket.recv(1024)
while 1:
msg = "Message to send"
clientsocket.sendall(msg)
clientsocket.close()
def listen(self):
host = ''
port = 55567
buf = 1024
addr = (host, port)
self.serversocket = socket(AF_INET, SOCK_STREAM)
self.serversocket.bind(addr)
self.serversocket.listen(2)
while 1:
if self.canExit:
print "trying to break"
break
print "Server is listening for connections\n"
clientsocket, clientaddr = self.serversocket.accept()
threading.Thread(target=self.handler, args=(clientsocket, clientaddr)).start()
print "closing the socket"
self.serversocket.close()
And here is a sample of my client code:
def SendFolder(self):
HOST = host=self.params["databaseLocation"] # The remote host
port = 55567
buf = 1024
addr = (host, port)
clientsocket = socket(AF_INET, SOCK_STREAM)
clientsocket.connect(addr)
if self.abortThisJob != False:
clientsocket.sendall(self.abortThisJob)
else:
clientsocket.sendall("Send Job")
self.listenThread = threading.Thread(target=self.listen, args=(clientsocket, buf))
self.listenThread.daemon= True
self.listenThread.start()
def listen(self, clientsocket, buf):
while 1:
data = raw_input(">> ")
clientsocket.send(data)
data = clientsocket.recv(buf)
print data

Categories