socket Почему получаю данные только один раз?

Нашёл где то пример работы сокета, клиент - сервер и хотел попробовать что то своё сделать, но столкнулся с такой проблемой, что он только один раз отвечает на запрос. При выборе ответа(1 или 2) он уже не шлёт данные. На сервер запрос попадает

  • client

     from random import randint
     import socket
     import ast
    
    
     def db(name):
             soc.send(f"{[name]}".encode())
             data = soc.recv(1024).decode()
             print(data)
    
             return ast.literal_eval(data)
    
     class Game:
             def __init__(self, name):
                     self.name = name
                     db(self.name)
                     Game.menu(self)
    
             def menu(self):
                     while 1:
                             a = int(input("1) начать игру\n2)Посмотреть статистику: "))
    
                             elif a == 2:
                                     Game.CheckLog(self)
    
    
             def CheckLog(self):
                     data = db(self.name)
                     print(f"Игр: {data[1]}")
                     if len(ast.literal_eval(data[3])) == 0:
                             return
    
                     poptk = 0
                     count = 0
                     for i in ast.literal_eval(data[3]):
                             poptk += i[1]
                             count += 1
                             print(f"Игра №{i[0]} | Попыток: {i[1]} | Загаданное число: {i[2]}")
    
                     print(f"Ср.Кол-во попыток: {round(poptk/count, 1)}")
    
     soc = socket.socket()
     soc.connect(("127.0.0.1", 8989))
    
     Game("merka")
    
  • server

     import socket
     import ast
     import sqlite3
    
     conn = sqlite3.connect("games.db") # или :memory:
     cursor = conn.cursor()
     cursor.execute("DROP TABLE users")
     cursor.execute(f"CREATE TABLE users(name INTEGER, games INTEGER, atmps INTEGER, log STRING, RandomNumber INTEGER);")
     conn.commit()
    
    
     soc = socket.create_server(("127.0.0.1", 8989))
     soc.listen(100)
    
     while True:
             try: con, addr = soc.accept()
    
             except socket.error:
                     pass
    
             else:
                     data = con.recv(1024).decode()
    
                     data = ast.literal_eval(data)
    
                     if len(data) == 1:
                             cursor.execute(f'SELECT * FROM users where name="{data[0]}"')
                             if cursor.fetchone()==None:
                                     cursor.execute(f"INSERT INTO users VALUES ('{data[0]}', '0', '0', '[]', '100')")#вводит все данные об участнике в БД
                                     conn.commit()
                             cursor.execute(f'SELECT * FROM users where name="{data[0]}"')
                             con.send((f"{cursor.fetchone()}").encode())
    
                     elif len(data) == 5:
                             cursor.execute(f'UPDATE users SET games={data[1]}, atmps={data[2]}, log={data[3]}, RandomNumber={data[4]} where name={data[0]}')
                             conn.commit()
    

В чём проблемка может быть?


Ответы (1 шт):

Автор решения: Azat

Просто вы неправильно эти данные принимаете. Если посмотреть описание функции recv, то она возвращает реально принятые данные, которые могут быть порезаны. В вашем случае нужно в цикле принимать данные, пока не будет достигнута нужная длина. А еще лучше, сделать заголовок, в котором будет храниться длина пакета, сначала принимаете заголовок, потом в цикле принимаете данные на нужную длину. Tcp гарантирует, что данные не перемешаются и будут приходить последовательно, но протокол не гарантирует, что данные будут приходить ровно теми же самыми кусками, которыми они были отправлены.

→ Ссылка