Home > Software design >  Creating a quiz using TCP socket programming
Creating a quiz using TCP socket programming

Time:10-22

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:

  1. It accepts a connection
  2. Waits for receiving bytes
  3. 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.

  • Related