I'm working in a sockets Python project, I encountered a bug in where I was not able to send two or more different messages from server to client. Here, for example, if the client requests to log in, the server answers with [CODE 10] Log in request and immediatly I wanted to respond if the log in was successful or not:
conn.send("[CODE 10] Log in request".encode(FORMAT))
success_login = login(current_username, current_password)
if success_login:
conn.send("[CODE 110] Log in successful".encode(FORMAT))
else:
conn.send("[CODE 111] Log in error".encode(FORMAT))
Instead I must press enter in client prompt between [CODE 10] Log in request and one of CODE 110 or CODE 111 response, is the anything wrong with my implementation?
I think it has to deal with client.py in the infinite loop but not sure how to fix it, can anyone tell me what I am doing wrong?
client.py
import socket
HEADER = 64
PORT = 9999
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'
SERVER = 'localhost'
ADDRESS = (SERVER,PORT)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 9999))
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(1024).decode(FORMAT))
while True:
msg = input()
if msg.encode() == DISSCONECT_MESSAGE:
print("[DISSCONECTED FROM SERVER]")
client.send(DISSCONECT_MESSAGE)
break
else:
send(msg)
server.py
import socket
import threading
from dbms import *
HEADER = 64
PORT = 9999
SERVER = socket.gethostbyname(socket.gethostname())
ADDRESS = ('',PORT)
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'
exec(open('dbms.py').read())
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDRESS)
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 == '0': # DISSCONECT_MESSAGE decoded
connected = False
break
elif msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
# sign in
if msg[:2] == "50":
new_usuario = msg.split()[1]
new_password = msg.split()[2]
conn.send("[CODE 50] Request to sign in".encode(FORMAT))
success_insert = insert(new_usuario , new_password)
if success_insert:
conn.send("[CODE 510] Sign in successful".encode(FORMAT))
else:
conn.send("[CODE 511] Sign in error".encode(FORMAT))
# log in
if msg[:2] == "10":
current_username = msg.split()[1]
current_password = msg.split()[2]
conn.send("[CODE 10] Solicitud para inicio de sesion".encode(FORMAT))
success_login = login(current_username, current_password)
if success_login:
conn.send("[CODE 110] Log in successful".encode(FORMAT))
else:
conn.send("[CODE 111] Log in error".encode(FORMAT))
print(f"[{addr}] {msg}")
conn.send("Message recived".encode(FORMAT))
print(f"[{addr}] DISSCONNECTED")
conn.close()
exit()
def start():
server.listen()
print(f"[LISTENING] Server is listening on {SERVER}")
while True:
conn, addr = server.accept() # Wait to a new connection
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount()-1}")
print("[STARTING] Server is starting...")
start()
exit()
dbms.py
import psycopg2
print("[IMPORT] dbms.py imported correctly")
conn_db = psycopg2.connect(database="aaa", user = "bbb", password = "ccc", host = "127.0.0.1", port = "5432")
print("[DATABASE] Successfully connected with database")
cursor = conn_db.cursor()
def insert(new_usuario,new_password):
try:
postgres_insert_query = """ INSERT INTO users (username, password) VALUES (%s,%s) """
record_to_insert = (new_usuario, new_password)
cursor.execute(postgres_insert_query, record_to_insert)
conn_db.commit()
count = cursor.rowcount
print(count, "[DATABASE] Record inserted successfully into USERS table")
return True
except (Exception, psycopg2.Error):
if(conn_db):
print("[ERROR] Failed to insert record into table USERS")
return False
def login(current_username, current_password):
""" Validate if a user already exists in DB """
try:
postgres_query = """SELECT username, password FROM users WHERE username = %s AND password = %s"""
record_to_validate = (current_username, current_password)
cursor.execute(postgres_query, record_to_validate)
count = cursor.rowcount
print(count, "[DATABASE] Credentials validated successfully")
return True
except (Exception, psycopg2.Error):
if(conn_db):
print("[ERROR] Failed to validate credentials")
return False
Related
I've been experimenting recently with password protecting sockets in python and I've come across an issue.
When checking the clients input with the servers set password the server seems to think the set password isn't the same as the password input by the user.
My first script: server.py
import socket
import threading
from requests import get
import uuid
HEADER = 64
PORT = 9090
#To connect over the internet change SERVER to your public IP
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, password):
print(f"[PNet] 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)
print(msg)
if msg == password:
connected = True
if msg != password:
print("Huh?")
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[PNet] {addr}: {msg}")
conn.send("[PNet] CLIENT: Message received.".encode(FORMAT))
conn.close()
def start():
print("[PNet] STARTING: Server is starting...")
print("[PNet] STARTING: Generating key...")
password = uuid.uuid4()
print(f"[PNet] FINALIZING: Key generated: {password}")
server.listen()
print(f"[PNet] LISTENING: Server is listening on {SERVER}.")
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr, password))
thread.start()
#print(f"[PNet] ACTIVE CONNECTIONS: {threading.activeCount() - 1}")
start()
and my second script: client.py
import socket
HEADER = 64
PORT = 9090
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
SERVER = input("[PNet] CLIENT: Server IP: ")
PASS = input("[PNet] SERVER: Enter password: ")
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(PASS)
connected = True
while connected:
msg = input("[PNet] CLIENT: Send a message: ")
if msg != DISCONNECT_MESSAGE:
send(msg)
else:
send(msg)
connected = False
when run, and the password is copied exactly from the terminal it still returns False. Thanks for your help :)
You are comapring UUID object with a string, thats why its returning false,
to check, put a print before comparing,
...
print(type(msg),type(password)) # will print <class 'str'> <class 'uuid.UUID'>
if msg == password:
connected = True
...
to solve it pass the password as string,
password = str(uuid.uuid4())
I have written an online chess app, using Python and Sockets. When I run the server and connect the clients, everything runs perfectly smooth. However, when I convert the client into an exe file and run it, the client isn't able to connect to the server anymore.
I have also tried to convert the server into an executable and it stopped working either. I think it has problems with the command server.listen(), because the ouput is only [STARTING] Server is starting... (More details in the server side code below)
Has anybody encountered problems too, when converting a socket app into an exe file? I didn't get any results with a Google search.
Shortened client side code:
import socket
HEADER = 64
PORT = 5050
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
NONE_MESSAGE = "!NONE"
OPPONENT_DISCONNECTED = "!OPPONENT_DISCONNECTED"
SERVER = "192.168.56.1"
ADDR = (SERVER, PORT)
def send(client, 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)
def recieve(client):
send(client, NONE_MESSAGE)
msg_length = client.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = client.recv(msg_length).decode(FORMAT)
if msg != NONE_MESSAGE:
return msg
return False
Server side code:
import socket
import threading
import random
HEADER = 64
PORT = 5050
SERVER = socket.gethostbyname(socket.gethostname())
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT"
NONE_MESSAGE = "!NONE"
OPPONENT_DISCONNECTED = "!OPPONENT_DISCONNECTED"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
def recieve(conn):
send(conn, NONE_MESSAGE)
msg_length = conn.recv(HEADER).decode(FORMAT)
if msg_length:
msg_length = int(msg_length)
msg = conn.recv(msg_length).decode(FORMAT)
if msg != NONE_MESSAGE:
return msg
return False
def send(conn, msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
conn.send(send_length)
conn.send(message)
def get_opponent(addr):
for c1, c2 in client_pairs:
if c1 == addr:
return c2
if c2 == addr:
return c1
return None
def handle_client(conn, addr):
global new_client
global new_client_name
name = recieve(conn)
if new_client:
print(f"[NEW CONNECTION] {addr} connected to {new_client}")
client_pairs.append((new_client, addr))
color = random.choice(['w', 'b'])
send(conn, color+new_client_name)
if color == 'w':
messages_to_send[new_client] = 'b'+name
else:
messages_to_send[new_client] = 'w'+name
new_client = None
new_client_name = None
else:
new_client_name = name
new_client = addr
print(f"[NEW CONNECTION] {addr} waiting")
connected = True
while connected:
if addr in messages_to_send.keys():
send(conn, messages_to_send[addr])
del messages_to_send[addr]
if addr in disconnects:
send(conn, OPPONENT_DISCONNECTED)
disconnects.remove(addr)
msg = recieve(conn)
if msg:
if msg == DISCONNECT_MESSAGE:
if new_client == addr:
new_client = None
opponent = get_opponent(addr)
if opponent:
disconnects.append(opponent)
connected = False
opponent = get_opponent(addr)
if opponent:
messages_to_send[opponent] = msg
print(f"[{addr}] {msg}")
conn.close()
new_client = None
new_client_name = None
messages_to_send = {}
client_pairs = []
disconnects = []
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()
So i'm also including the server side of the code, but the issues in the client side. It's a simple TCP client socket code.The thing is that in line 21, after the first while loop (i've also commented in the code to where i'm referring to), i'm asking for user input.
What then happens is that when more user connects, the chat screen of any user doesn't gets updated unless they press enter, as you can see, it only continues after an input is given to the 'message' variable.
Now i do know that threading need to be done in here, but i've not really got enough knowledge related to that. So if someone could kindly guide me or help me modify the code so that the chat gets updated without the need to enter.
Cient Code (Issue in line 21, after first while loop...commented)
from socket import *
import select
import errno
import sys
header_length = 10
ip = "127.0.0.1"
port = 1234
my_username = input("Username: ")
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((ip, port))
client_socket.setblocking(False)
username = my_username.encode()
username_header = f"{len(username):<{header_length}}".encode()
client_socket.send(username_header + username)
while True:
#Where my issue is
message = input(f"{my_username} > ")
if message:
message = message.encode()
message_header = f"{len(message):<{header_length}}".encode()
client_socket.send(message_header + message)
try:
while True:
#receive messages
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().strip())
username = client_socket.recv(username_length).decode()
message_header = client_socket.recv(header_length)
message_length = int(message_header.decode().strip())
message = client_socket.recv(message_length).decode()
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()
Server Code (Just if someone need):
from socket import *
import select
header_length = 10
ip = "127.0.0.1"
port = 1234
server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server_socket.bind((ip, port))
server_socket.listen()
socket_list = [server_socket]
clients = {}
#Handles message receiving
def recieve_message(client_socket):
try:
message_header = client_socket.recv(header_length)
if not len(message_header):
return False
message_length = int(message_header.decode().strip())
return {'header': message_header, 'data': client_socket.recv(message_length)}
except:
return False
print(f'Listening for connections on {ip}:{port}...')
while True:
read_sockets, _, exception_sockets = select.select(socket_list, [], socket_list)
for notified_socket in read_sockets:
if notified_socket == server_socket:
client_socket, client_address = server_socket.accept()
user = recieve_message(client_socket)
if user is False:
continue
socket_list.append(client_socket)
clients[client_socket] = user
print(f"Accepted new connection from {client_address[0]}:{client_address[1]} username:{user['data'].decode()}")
else:
message = recieve_message(notified_socket)
if message is False:
print(f"Closed connection from {clients[notified_socket]['data'].decode()}")
socket_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
print(f"Recieved messasge from {user['data'].decode()}: {message['data'].decode()}")
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:
socket_list.remove(notified_socket)
del clients[notified_socket]
I've also included the image...as you can see as i typed hello in cliend 1's window, client 2's doesnt show it. And it will not until i input something and press enter
Thanks a lot :)
Why do you not use select.select for the client as you do for the server?
It works perfectly.
Linux version
from socket import *
import select
import errno
import sys
def prompt(username):
sys.stdout.write(f"{username} > ")
sys.stdout.flush()
header_length = 10
ip = "127.0.0.1"
port = 1234
my_username = input("Username: ")
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((ip, port))
client_socket.setblocking(False)
username = my_username.encode()
username_header = f"{len(username):<{header_length}}".encode()
client_socket.send(username_header + username)
while True:
socket_list = [sys.stdin, client_socket]
prompt(my_username)
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for socket in read_sockets:
try:
if socket == sys.stdin:
message = sys.stdin.readline()
message = message.encode()
message_header = f"{len(message):<{header_length}}".encode()
client_socket.send(message_header + message)
elif socket == client_socket:
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().strip())
username = client_socket.recv(username_length).decode()
message_header = client_socket.recv(header_length)
message_length = int(message_header.decode().strip())
message = client_socket.recv(message_length).decode()
print(f"\n{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()
Windows/Linux version (because of select restriction)
Note:
File objects on Windows are not acceptable, but sockets are. On Windows, the
underlying select() function is provided by the WinSock library, and does not
handle file descriptors that don’t originate from WinSock.
import threading
from socket import *
import select
import errno
import sys
def prompt(username):
sys.stdout.write(f"{username} > ")
sys.stdout.flush()
def redirect_sdtin(dest):
for ln in sys.stdin:
dest.send(ln.encode())
header_length = 10
ip = "127.0.0.1"
port = 1234
my_username = input("Username: ")
stdin_in, stdin_out = socketpair()
threading.Thread(target=redirect_sdtin, args=(stdin_in,), daemon=True).start()
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((ip, port))
client_socket.setblocking(False)
username = my_username.encode()
username_header = f"{len(username):<{header_length}}".encode()
client_socket.send(username_header + username)
while True:
socket_list = [stdin_out, client_socket]
prompt(my_username)
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for socket in read_sockets:
try:
if socket == stdin_out:
message = stdin_out.recv(1024)
message_header = f"{len(message):<{header_length}}".encode()
client_socket.send(message_header + message)
elif socket == client_socket:
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().strip())
username = client_socket.recv(username_length).decode()
message_header = client_socket.recv(header_length)
message_length = int(message_header.decode().strip())
message = client_socket.recv(message_length).decode()
print(f"\n{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()
The server is not broadcasting the sent messages back to the clients. The server is also not seeing the messages but is seeing that there is something being sent via the broadcast. The client who sends the message should not be sent the message again.
ChatClient
import socket, threading
def send():
while True:
msg = raw_input('\nMe : ')
cli_sock.send(msg)
def receive():
while True:
sen_name = cli_sock.recv(1024)
data = cli_sock.recv(1024)
print('\n' + str(sen_name) + ' : ' + str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
uname = raw_input('Enter your name to enter the chat : ')
cli_sock.send(uname)
thread_send = threading.Thread(target = send)
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
ChatServer
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
thread_client = threading.Thread(target = broadcast_usr, args=
[uname, cli_sock])
thread_client.start()
def broadcast_usr(uname, cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
print "{0} spoke".format(uname)
b_usr(cli_sock, uname, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for client in CONNECTION_LIST:
if client[1] != cs_sock:
client[1].send(sen_name)
client[1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
The expected should be if user is Dan(me):
John: Hi
Me: Hi
Me: How are you
John: Great
Stephen: Awesome
The actual is only displaying the "Me" on the specific client's side
I'm trying to send a message from Client to Server using socket. For some reason, the message is not received. example: the client sends 'myname_0' the server needs to receive it and decode it and continue further.
Listener:
import socket
class SocketSender():
def __init__(self):
self.sock = socket.socket()
ip = socket.gethostname() # IP to server.
port = 7000
self.sock.bind((ip, port))
print("Binding successful.")
self.sock.listen(2)
print("Listening....")
self.listening = True
# self.sock.connect((ip, port))
# print("Connected.")
def sendpacket(self, packet):
self.sock.send(packet.encode())
def receivepacket(self):
while self.listening:
con, addr = self.sock.accept()
print("Receiving packet from " + str(addr))
packet = self.sock.recv(1024).decode("utf-8")
return str(packet)
Sender:
import socket
sock = socket.socket()
ip = socket.gethostname()
port = 7000
sock.connect((ip, port))
print("connection to " + ip)
message = "test_0"
sock.send(message.encode("utf-8"))
When run:
import GUI
import SocketSender
# Entry: 0, Exit: 1
gui = GUI.ASGui()
# gui.run()
socket = SocketSender.SocketSender()
id = input()
while 1 == 1:
packet = socket.receivepacket()
name, state = packet.split("_")
break
if state == 0:
print("Welcome back, " + name)
else:
if state == 1:
print("Goodbye, " + name)
I do get the outputs Listening and Binded. But I am unable to receive a message. Help would be appreciated. Thank you.