I am trying to make a quiz game that runs over a TCP server/client. Can anyone help me get the server to send the second question after the user enters the answer on the client side? Right now when I enter my first answer, whether its right or wrong the second question is never sent. I included my code below for reference:
server
from socket import *
from random import choice
serverPort = 13000
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('', serverPort))
serverSocket.listen(1)
correct = 0
print ('The server is ready to receive')
fullquiz= []
questions = []
answers = []
with open ("quiz.txt") as data_file: #this sections opens the quiz file and splits it into questions and answers
for line in data_file:
data = (line.split(','))
fullquiz = data
questions = fullquiz[0::2] #this is the questions list
answers = fullquiz[1::2] #this is the answer list
while True:
connectionSocket, addr = serverSocket.accept() #addresses the server to the socket
sentence = connectionSocket.recv(1024)
if (correct < 3):
a = choice(list(questions))
connectionSocket.send(a.encode())
print(sentence)
print(correct)
else:
connectionSocket.close()
client
from socket import *
serverName = '127.0.0.1'
serverPort = 13000
correct = 0
clientSocket = socket(AF_INET, SOCK_STREAM)
while True:
clientSocket.connect((serverName,serverPort))
sentence = 'client is connected'
clientSocket.send(sentence.encode())
while True:
if (correct < 3):
modifiedSentence = clientSocket.recv(1024)
print ('Question: ', modifiedSentence.decode())
answer = input('What is your answer: ')
clientSocket.send(answer.encode())
else:
clientSocket.close()
CodePudding user response:
There are some other potential problems with your current code, but I just want to address your specific issue.
look what your server does:
- It accepts a connection
- Waits for receiving bytes
- Sends some bytes to the client socket
then ? It again stops at the line connectionSocket, addr = serverSocket.accept()
. It blocks to receive another connection.
This is not what you want. Instead, after accepting a connection, you have to constantly read and write to the socket.
Here I slightly modified your code to make it easier to run:
Server.py
from socket import *
from random import choice
serverPort = 13000
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(("", serverPort))
serverSocket.listen(1)
questions = ["Q1", "Q2", "Q3"]
answers = ["A1", "A2", "A3"]
while True:
try:
print("Ready to accept connection")
connectionSocket, addr = serverSocket.accept()
while True:
sentence = connectionSocket.recv(1024)
print(sentence)
a = choice(list(questions))
connectionSocket.send(a.encode())
finally:
serverSocket.close()
Client.py
from socket import *
serverName = "127.0.0.1"
serverPort = 13000
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))
sentence = "client is connected"
clientSocket.send(sentence.encode())
try:
while True:
modifiedSentence = clientSocket.recv(1024)
print("Question: ", modifiedSentence.decode())
answer = input("What is your answer: ")
clientSocket.send(answer.encode())
finally:
clientSocket.close()
CodePudding user response:
Look at this code:
while True:
connectionSocket, addr = serverSocket.accept() #addresses the server to the socket
sentence = connectionSocket.recv(1024)
if (correct < 3):
a = choice(list(questions))
connectionSocket.send(a.encode())
print(sentence)
print(correct)
else:
connectionSocket.close()
It does essentially:
Loop:
accept a connection
receive something from client
send a question
That seems backwards, and should send more than one question per connection. How about:
Loop:
accept a connection
for each question:
send a question
receive an answer
send response (correct/incorrect)
Also note TCP is a streaming protocol, meaning send/recv isn't 1:1 and you should buffer reads and check that you have a complete message. One way is to use newlines to delineate "messages". See socket.makefile
for a way to wrap a socket in a file-like object so you can use .readline()
and .write(msg '\n')
to ensure reading a line of data at a time.
Give that a try and post another question if you get stuck.