I am having a problem with my program where my server receives data that I am NOT sending from my client
Connection from: ('192.168.0.17', 58167)
data recieved : __UserLogin123__
User Login requested
James Green at recieve login
James Green in accessCodes
93
{93: ['James', 'Green']}
Found
User Found
3
data recieved : __QUIT____CHECK_SCORE__
Incorrect code received
done
Connection from: ('192.168.0.17', 58182)
data recieved : __UserLogin123__
User Login requested
James Green at recieve login
James Green in accessCodes
93
{93: ['James', 'Green']}
Found
User Found
3
data recieved : __QUIT____CHECK_SCORE__
Incorrect code received
the last "data recieved : QUIT___CHECK_SCORE" makes absolutely no sense, I use codes to access methods from classes which will send certain types of data telling the server if i want to (for example) add a user to a database, and it does this by accessing a dictionary storing methods with string keys.
Here is the "handler" and "main" from my client:
def Main():
global s
host = "192.168.0.17"
port = 5000
ID = "__UserLogin123__"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((host, port))
s.send(str.encode(ID))
setupCheck = s.recv(2048).decode()
time.sleep(1)
if setupCheck == "__dataReceived__":
username = input("Enter username : ")
password = input("Enter password : ")
userDetails = (username, password)
dataString = pickle.dumps(userDetails)
s.send(dataString)
access = s.recv(2048).decode()
print(access)
if access == "__ACCESS_GRANTED__":
permissionLvl = s.recv(2048).decode()
print(permissionLvl)
if permissionLvl == "1":
ClientUser = User(username,password)
elif permissionLvl == "2":
ClientUser = Admin(username,password)
elif permissionLvl == "3":
ClientUser = HeadAdmin(username,password)
else:
print("SOMETHING WRONG SOMETHING WROGN")
time.sleep(3)
handler(ClientUser)
else:
print("Incorrect details provided")
def handler(ClientUser):
function_dict = {"__QUIT__": ClientUser.quit(), "__PLAY_GAME__": ClientUser.playGame(),
"__CHECK_SCORE__": ClientUser.checkScore(),"__CHECK_USERS__": ClientUser.checkUsers(),
"__ADD_ASSIGNMENT__": ClientUser.addAssignment(),"__REMOVE_ASSIGNMENT__": ClientUser.removeAssignment(),
"__EDIT_ASSIGNMENT__": ClientUser.editAssignment(), "__ADD_USER__": ClientUser.addUser(),
"__EDIT_USER__": ClientUser.editUser(), "__REMOVE_USER__": ClientUser.removeUser(),
"__CREATE_GROUP__": ClientUser.createGroup()}
while True:
checkDataReady = s.recv(2048).decode()
print(checkDataReady)
if checkDataReady == "__dataExchangeReady__":
print("Available Commands:")
ClientUser.availableCommands()
commandChoice = ""
while commandChoice not in choices:
while True:
try:
commandChoice = int(input("Please enter your choice (number) \n-> "))
except ValueError:
print("Please only enter integers")
finally:
if commandChoice > 14 or commandChoice < 0:
print("Please only enter one of the numbers listed")
else:
break
commandChoice = choices[commandChoice]
print(commandChoice)
checkString = "Are you sure you want to : " + commandChoice + "? (Y/N) -> "
check = input(checkString)
if check.upper() == "N":
commandChoice = ""
print("executing function")
function_dict[commandChoice]
and here is some server side code that I think is affiliated with the problem:
def handler(conn, addr):
print("done")
print("Connection from: " + str(addr))
dbSetup()
while True:
time.sleep(1)
data = conn.recv(2048).decode()
print("data recieved : " + data)
if data == "__QUIT__" or not data:
print("Connection closed")
print("Connection Closed by", addr[0], ":", addr[1])
break
elif data in accessCodes:
accessCodesHandler(data)
elif data in commandCodes:
commandCodesHandler(data)
else:
print("Incorrect code received")
break
conn.send(str.encode("__dataExchangeReady__"))
conn.close()
def accessCodesHandler(accessCode):
if accessCode == accessCodes[0]:
print("User Login requested")
username, password = receiveLoginDetails()
print(username,password, "in accessCodes")
userCheck = getUser_InHash(username, password)
if userCheck == True:
userPermissionLvl = str(getUser_InUserDb(username,"")[2])
print("User Found")
conn.send(str.encode("__ACCESS_GRANTED__"))
time.sleep(1)
print(userPermissionLvl)
conn.send(str.encode(userPermissionLvl))
else:
print("User not found")
conn.send(str.encode("__AccessDenied__"))
else:
print("Head admin setup protocol executed")
username, password = receiveLoginDetails()
addUser_InHash(username, password, 3)
I can see no reason why my server would ouput "QUIT__CHECK_SCORE" as i dont send any data that says that explicitly, my error code for client side is:
Enter username : James
Enter password : Green
__ACCESS_GRANTED__
3
James
Green
Traceback (most recent call last):
File "C:/Users/Green/Desktop/Py Proj/Project_Client.py", line 197, in <module>
Main()
File "C:/Users/Green/Desktop/Py Proj/Project_Client.py", line 153, in Main
handler(ClientUser)
File "C:/Users/Green/Desktop/Py Proj/Project_Client.py", line 161, in handler
"__ADD_ASSIGNMENT__": ClientUser.addAssignment(),"__REMOVE_ASSIGNMENT__": ClientUser.removeAssignment(),
File "C:/Users/Green/Desktop/Py Proj/Project_Client.py", line 37, in removeAssignment
s.send(str.encode("__REMOVE_ASSIGNMENT__"))
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
Process finished with exit code 1
Sorry if this isnt enough information, I really dont know what is wrong with the program. Thanks in advance for any help
Your dictionary initialization code is suspect.
The following actually invokes funca() and stores its return value as the value associated with the key 'a':
d = { 'a': funca() }
If you want to store the funca function itself, for later lookup and invocation, then use:
d = { 'a': funca }
Related
I am trying to program a login system using the library 'socket'. With six failed attempts the server side should do some stuff, but the failed attempts are not counted. Thanks if you can help me.
Client side:
# login logic
while True:
# Generate hashed password
password = input("Password: ")
hashed_password = hashlib.sha512(password.encode()).hexdigest()
s.sendall(hashed_password.encode())
is_password_correct = s.recv(1024)
if is_password_correct.decode() == "correct_password":
print(f"{green_sign} You have successfully authorized!")
break
elif is_password_correct.decode() == "wrong_password":
password_trials = s.recv(1024)
print(f"{yellow_sign} Wrong password! Try again... ({int(password_trials.decode())} / 6)")
Server side:
# login logic
password_trials = 0
while True:
# check hashed password
recv_password = conn.recv(1024)
if recv_password.decode() == stored_hashed_password:
password_trials = 0
print(f"{gray_sign} User has authorized successfully!")
conn.sendall(b"correct_password")
break
elif recv_password.decode() != stored_hashed_password:
password_trials += 1
conn.sendall(b"wrong_password")
conn.sendall(str(password_tries).encode())
if password_trials == 6:
""" Do some stuff """
My target is print the message from function result on the client's screen. But only ONE client can received the message...
The part of client.py is here
def PlayGame(clientSocket, msg):
invalid = "NO!"
if ("/guess " in msg):
msg1 = msg.split(" ")[1]
print("Hi1\n")
if msg1 == "true" or msg1 == "false":
print("Hi11")
clientSocket.send(msg1.encode())
print(clientSocket.recv(1024).decode())
print("!")
return '1'
else:
clientSocket.send(invalid.encode())
print(clientSocket.recv(1024).decode())
print("2")
return '2'
elif msg == "":
return '2'
else:
clientSocket.send(invalid.encode())
print(clientSocket.recv(1024).decode())
print("3")
return '2'
def main(argv):
msg=""
while (PlayGame(clientSocket, msg)!=1):
msg = input()
Any part of the server.py
guess_box = []
guess = bool(random.randint(0, 1))
def result(connectionSocket, guess_box, addr, addr_l):
a = 0
if(guess_box[0] == guess_box[1]):
msg = "Tie!!"
connectionSocket.send(msg.encode())
return '2'
elif(guess_box[0] == guess):
msg = "Player 1 Wins!"
a+=1
connectionSocket.send(msg.encode())
return '2'
elif(guess_box[1] == guess):
msg = "Player 2 Wins!"
a+=1
connectionSocket.send(msg.encode())
return '2'
def TF(connectionSocket, var, guess_box, addr, addr_l):
msg = connectionSocket.recv(1024).decode()
print("recv:",msg)
if(msg == 'true'):
msg = 'True'
var = str(var)
msg = bool(msg == var)
guess_box.append(msg)
return 'ok'
elif(msg == 'false'):
msg = 'False'
var = str(var)
msg = bool(msg == var)
guess_box.append(msg)
return 'ok'
else:
print(msg)
statement = "4002 Unrecognized message!!"
connectionSocket.send(statement.encode())
return 'again'
class ServerThread(threading.Thread):
def __init__(self, client):
threading.Thread.__init__(self)
self.client = client
def run(self):
...
print("guess is:", guess)
while (len(guess_box) != 2):
TF(connectionSocket, guess, guess_box, addr, addr_l)
print("start")
result(connectionSocket, guess_box, addr, addr_l)
...
Regarding only the one problem you address:
print the message from function result on the client's screen. But only ONE client can received the message
The problem comes from the use of a different thread for each client. The thread which receives a guess as first stays in its
while (len(guess_box) != 2):
print(guess_box)
TF(connectionSocket, guess, guess_box)
loop and waits for another message, which doesn't come. The thread which receives a guess as second sends the result to its own client only.
I don't think there's a sensible way to fix this while keeping this dthreaded approach.
Can I change the structure of my code by using those functions I implemented?
Here's a substitute for the while True loop in server_run that doesn't require changes in those functions other than server_run.
from select import select
connections = []
room_connection = {}
for reads in iter(lambda: select([serverSocket]+connections, [], [])[0], []):
for ready in reads: # for each socket which select reports is readable
if ready == serverSocket: # it's the server socket, accept new client
connectionSocket, addr = serverSocket.accept()
connections.append(connectionSocket)# store the connection socket
while RecvFromClient(connectionSocket) == "NO": pass
else: # message (or disconnect) from a client
try: var = GameHallMsg(ready, ready, connections)
except socket.error: var = 'bye'
if var == 'bye': # client finished, remove from list
connections.remove(ready)
ready.close()
elif var == 'wait': # store first player's connection
room_connection[current_rm_num.pop()] = ready
elif var == 'NO':
rtn_msg_4 = "4002 Unrecognized message"
ready.send(rtn_msg_4.encode())
elif var == 'jump':
readyroom = current_rm_num.pop()
# find and notify other player in the room
other = room_connection.pop(readyroom)
rtn_msg_2 = "3012 Game started. Please guess true or false"
other.send(rtn_msg_2.encode())
print("guess is:", guess)
# query and inform both players
guess_box = []
while TF(ready, True, guess_box) != 'ok': pass
while TF(other, True, guess_box) != 'ok': pass
result(ready, guess_box, ('', 0), [0])
result(other, guess_box, ('', 1), [0, 1])
room[readyroom] = 0
I'm new to socket and python programming, and I'm trying to build a simple game between server and client. Basically server types in a word and the client tries to guess another word starting with the first two letters of the server's word.Example: Server:computer|Client:erase|Server:secondary|Client:rye
I've got a loop that takes messages from client and sends it back to it and vice versa:
#server.py
while True:
message_sent = input(str("Me : "))
conn.send(message_sent.encode())
message_received = conn.recv(1024).decode()
first = message_sent[:2]
last = message_received[-2:]
print(s_name, ":", message_received)
if first != last:
message = "wrong word entered "
conn.send(message.encode())
print("\n")
break
and client.py:
#client.py
while True:
message_received = s.recv(1024).decode()
print(s_name, ":", message_received)
message_sent = input(str("Me : "))
first = message_sent[:2]
last = message_received[-2:]
if first != last:
message = "wrong word typed "
s.send(message.encode())
print("\n")
break
s.send(message_sent.encode())
when I send an incorrect word to the server from the client I can get the "wrong word typed" but when I send it other way it just accepts the word and keeps going. What am I doing wrong here?
in the server add:
while True:
message_sent = input(str("Me : "))
conn.send(message_sent.encode())
message_received = conn.recv(1024).decode()
if message_received == "wrongword":
print('GAME OVER')
print('Winner is Server')
break
first = message_sent[:2]
last = message_received[-2:]
print(s_name, ":", message_received)
if first != last:
message = "wrongword"
conn.send(message.encode())
print("\n")
break
in the client:
while True:
message_received = s.recv(1024).decode()
if message_received == "wrongword":
print('GAME OVER')
print('Winner is Client')
break
print(s_name, ":", message_received)
message_sent = input(str("Me : "))
first = message_sent[:2]
last = message_received[-2:]
if first != last:
message = "wrongword"
s.send(message.encode())
print("\n")
break
s.send(message_sent.encode())
def hand():
print("Wrong port format")
er()
def er():
try:
host=input("Host: ")
serverPort=(input("Port: "))
try:
Port=int(serverPort)
except Exception:
hand()
return (host,int(serverPort))
except Exception:
return("Wrong")
serverPorti=er()
print((serverPorti))
When I run it returns Wrong, I want the user to input the host and the port but if the user inputs a text(letters) in port number it should call back the function er(), it does call back but the return even after I input the right port number returns wrong.
Because i am bored i made it working for you
def getHostPort():
host = ''
serverPort = ''
inputCorrect = False
while not inputCorrect:
try:
host = input("Host: ")
serverPort = int(input("Port: "))
inputCorrect = True
except Exception:
print("wrong port")
continue
return (host,int(serverPort))
serverPorti=getHostPort()
print((serverPorti))
I honestly have no idea why this is happening, I assume due to it not being on stack-exchange it's a very n00by mistake on my part. so here's the error:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
UnboundLocalError: local variable 'socket' referenced before assignment
tcpServer.py
import socket
def Main():
UID = 1001
sockets = []
users = [] ## create usernames list
sessionLimit = input("session Queue Limit: ")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.1.74', 12127))
s.listen(sessionLimit) ## listen for 1 connection at a time
while True:
c, addr = s.accept()
sockets.append(c)
users.append(c.recv(1024).decode('utf-8'))
print("Connection from " + str(addr))
data = c.recv(1024).decode('utf-8') ## recieve 1024 bytes from client at a time, and then decode it into utf-8
if not data:
break
temp == data
temp.split(" ")
if temp[0] == "//": ## check to see if user has sent command
if temp[1] == "msg":
for i in range(len(users)):
if users[i] == temp[2]:
sockets[i].send((" ".join(temp[::2])).encode('utf-8'))
else: ## else, send data to all users. Could just use s.sendall(data.encode('utf-8'))
for socket in sockets:
socket.send(data.encode('utf-8')) ## send to sockets[socket]
##print("From connected user: " + data)
##data = data.upper()
##print("Sending: " + data)
##c.send(data.encode('utf-8'))
## command listening
commands = input("-> ")
commands.split(" ")
if commands[0] == "exit":
c.close() ## close connection
elif commands[0] == "/msg":
for i in range(len(users)):
if users[i] == commands[1]:
sockets[i].send((" ".join(commands[::1])).encode('utf-8'))
"""
elif commands[0] == "/rename": ## dont implement yet, due to users[] length changing
for i in range(len(users)):
if users[i] == commands[1]:
sockets[i].send("<server_" + UID + "> rename " + commands[2].encode('utf-8'))
"""
c.close()
if __name__ == "__main__":
Main()
Thanks for any help !
- Jacob
The issue is that you're using the variable name socket in the context of your Main() function when you do the following code block:
for socket in sockets:
socket.send(data.encode('utf-8')) ## send to sockets[socket]
That's causing an naming issue with the socket library. If you change that to:
for sock in sockets:
sock.send(data.encode('utf-8')) ## send to sockets[socket]
It will start to work. I also had to indent your code differently to ensure it was all in the Main() function you set up, and had to ensure the input() was parsed as an int. For reference, here's the full code block working for me:
import socket
def Main():
UID = 1001
sockets = []
users = [] ## create usernames list
sessionLimit = int(input("session Queue Limit: "))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.1.74', 12127))
s.listen(sessionLimit) ## listen for 1 connection at a time
while True:
c, addr = s.accept()
sockets.append(c)
users.append(c.recv(1024).decode('utf-8'))
print("Connection from " + str(addr))
data = c.recv(1024).decode('utf-8') ## recieve 1024 bytes from client at a time, and then decode it into utf-8
if not data:
break
temp == data
temp.split(" ")
if temp[0] == "//": ## check to see if user has sent command
if temp[1] == "msg":
for i in range(len(users)):
if users[i] == temp[2]:
sockets[i].send((" ".join(temp[::2])).encode('utf-8'))
else: ## else, send data to all users. Could just use s.sendall(data.encode('utf-8'))
for sock in sockets:
sock.send(data.encode('utf-8')) ## send to sockets[socket]
##print("From connected user: " + data)
##data = data.upper()
##print("Sending: " + data)
##c.send(data.encode('utf-8'))
## command listening
commands = input("-> ")
commands.split(" ")
if commands[0] == "exit":
c.close() ## close connection
elif commands[0] == "/msg":
for i in range(len(users)):
if users[i] == commands[1]:
sockets[i].send((" ".join(commands[::1])).encode('utf-8'))
"""
elif commands[0] == "/rename": ## dont implement yet, due to users[] length changing
for i in range(len(users)):
if users[i] == commands[1]:
sockets[i].send("<server_" + UID + "> rename " + commands[2].encode('utf-8'))
"""
c.close()
if __name__ == "__main__":
Main()