Возникли проблемы с сохранением активности сокета Python

Я пытаюсь создать клиент-серверную консольную игру, но у меня возникают проблемы с сохранением активности сокета, кажется, он закрывается до того, как я вызвал close(), и я не могу понять, почему.

Я прочитал тему здесь, но я вызвал connect() вне цикла while, поскольку логика это уже имело смысл для меня, прежде чем я попытался запустить его, но я все еще получаю сообщение об ошибке из оболочки сервера:

ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

Пока я не получаю сообщение об ошибке в клиентской оболочке, она просто завершает работу сразу после запуска, что также происходит при возникновении ошибки сервера.
После исправления ошибок, отмеченных в комментариях, клиент теперь также показывает ошибку, указывающую, что connected не определено при попытке запустить цикл while, но должно быть так, поскольку Connect() запускается до входа в цикл, который должен был установить connected = True, поэтому цикл должен выполняться, но не выполняется. Я сомневаюсь, что это вообще связано с проблемой сервера, но в чем может быть проблема?

Я поставлю код для обоих ниже:

Клиент

import socket

def GetData():
    data = s.recv(1000).decode()
    if (data == "closing"):
        connected = False
    else:
        print(data)

def SendData():
    tdata = input("")
    s.send(data.encode())


def Connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("127.0.0.1", 2222))
    connected = True


global connected
Connect()

while (connected == True):
    GetData()
    if (connected == False):
        s.close()
        break
    SendData()

Сервер

import socket
import random

def TheMainGame():
    print ("started TheMainGame")  # Remove after debug
    def within(val, goal):
        print ("Runing 'within' function")  # Remove after debug
        i = abs(val - goal)
        if (i <= 5):
            return True
        else:
            return False

    def Guess():
        print ("Running 'Guess' function")  # Remove after debug
        while True:
            print ("Entered while loop")  # Remove after debug
            data = "What is your guess?"
            c.send(data.encode())
            print ("Sent data")  # Remove after debug
            t = c.recv(1000).decode()
            print ("Got data")  # Remove after debug
            if (t == x):
                data = "Correct!"
                c.send(data.encode())
                data = "closing"
                c.send(data.encode())
                c.close()
                break
            elif (within(t,x) == True):
                data = "You're close!"
                c.send(data.encode())
            elif (within(t,x) == False):
                data = "Try again"
                c.send(data.encode())
            else:
                data = "There was an error computing the value"
                c.send(data.encode())
                c.close()
                break

    x = random.randrange(1, 20, 1)
    Guess()

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1", 2222))
s.listen(5)
global data
while True:
    (c,a) = s.accept()
    print("Received connection from", a)  # Remove after debug
    data = "Hello %s" %a[0]  # Remove after debug
    c.send(data.encode())  # Remove after debug
    TheMainGame()

Ошибка в оболочке сервера относится к строке 19, поэтому сервер пытается задать вопрос клиенту, что также является второй раз, когда он пытается отправить данные клиенту, но попытка так и не происходит, поэтому я думаю, что сокет закрывается, хотя я никогда не говорил об этом до этого момента, поскольку он даже не смог проверить, t == x. Что вызывает закрытие сокета?


person PairedPrototype    schedule 31.10.2015    source источник
comment
Вы допустили ошибку connected в Connect() в своем клиентском коде. Кроме того, если вы собираетесь присвоить значение глобальной переменной, вы должны использовать ключевое слово global с именем переменной в области действия функции.   -  person Joel Cornett    schedule 31.10.2015
comment
@JoelCornett О, так я и сделал! После исправления я сделал connected глобальным (я отредактирую свой вопрос, чтобы отразить изменение), и теперь я также получаю сообщение об ошибке в клиенте в цикле while, в котором говорится, что connected не определено, но это должно быть, так как я запустил Connect() который установит его в True перед входом в цикл...   -  person PairedPrototype    schedule 31.10.2015
comment
@JoelCornett Проблема теперь решена, спасибо за помощь! Это было бы решено еще быстрее, если бы я освежил свои знания о том, как работают глобальные переменные. Еще раз спасибо.   -  person PairedPrototype    schedule 31.10.2015


Ответы (1)


Вы неправильно используете global в клиенте.

в основном теле у вас есть global connected. Это неправильно.

Вместо этого в начало файла поместите:

import socket
connected = False

Затем в функции Connect извлеките глобальную переменную области действия:

def Connect():
    global connected
    ...

Ключевое слово global указывает функции использовать переменную из глобальной области видимости, а не определять их.

Примечание. В этом коде есть и другие ошибки, которые вам нужно будет просмотреть и устранить.

  1. Вы сделали то же самое в server.py
  2. Вы пытаетесь сослаться на сокет s в функциях GetData и SendData, но s является локальным только внутри функции подключения (это означает, что соединение будет разорвано, как только функция существует.
person mplf    schedule 31.10.2015
comment
О, вот как работает глобалка! Спасибо за разъяснение, сейчас исправляю код. - person PairedPrototype; 31.10.2015
comment
Благодарю вас! Оно работает! Теперь у меня просто есть логические ошибки, которые мне нужно освежить. Большое спасибо. - person PairedPrototype; 31.10.2015