Почему не могу записать данные в текстовый файл с помощью сервера?
Добрый день я новичок в программировании на пайтон, может кто-нибудь объяснить, почему я не могу записать в txt файл ввод клиента? Вкратце поясню чего я хочу добиться: обрабатывать с помощью сервера запросы клиента, записывая их в текстовый файл, запись происходит со стороны сервера.
Вроде бы код выполняется, тестировал его отдельно без использования сокетов и это работало, но видимо сокет закрывается до того, как атрибут data_to_write, объекта handler получает переменную get_command. Либо же сокет вообще не передает переменную в качестве атрибута методу change_file()
Подскажите что я делаю не так?
Ниже представлен код сервера:
import socket
from threading import Thread
path_to_file = "qwerty.txt"
class Server:
def __init__(self):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def set_up(self):
self.server.bind(("127.0.0.1", 9099))
self.server.listen(5)
print("Server is listening")
self.accept_sockets()
def listen_socket(self, listened_socket=None):
print("Listening user")
while True:
data = listened_socket.recv(5000)
self.get_command = data.decode("utf-8")
print(f"\nUser sent <{self.get_command}>")
def send_to_client(self, send_socket=None):
while True:
send_to_client = input("Введите значение:").encode("utf-8")
send_socket.send(send_to_client)
def accept_sockets(self):
while True:
user_socket, address = self.server.accept()
print(f"User <{address[0]}> connected!")
listen_thread = Thread(
target=self.listen_socket,
args=(user_socket,)
)
listen_thread.start()
send_thread = Thread(
target=self.send_to_client,
args=(user_socket,)
)
send_thread.start()
class Handler:
def change_file(self, data_to_write):
with open(path_to_file, "ab") as f:
f.write(data_to_write)
if __name__ == "__main__":
server = Server()
server.set_up()
handler = Handler()
handler.change_file(server.get_command)
Код клиента:
import socket
from threading import Thread
class Client:
def __init__(self):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Client connection")
def set_up(self):
self.client.connect(("127.0.0.1", 9099))
send_thread = Thread(target=self.send_data)
send_thread.start()
listen_thread = Thread(target=self.listen_socket)
listen_thread.start()
def send_data(self):
while True:
msg = input("Enter your messages: ")
self.client.send(msg.encode("utf-8"))
def listen_socket(self):
while True:
data = self.client.recv(5000)
print("Полученное сообщение: ", data.decode("utf-8"))
if __name__ == '__main__':
client = Client()
client.set_up()
Ответы (1 шт):
Вот мой маленький пример Server:
import asyncio
class Server(object):
def __init__(self, ip: str, port: int, limit: int):
self.ip = ip
self.port = port
self.limit = limit
async def _reading_message(self, reader: asyncio) -> str:
"""
Функция получения сообщения по открытому соединению
:param reader: asyncio
:return: received_message: str
"""
received_message = ''
while True:
message = await reader.read(100)
message = message.decode()
received_message += message
if '\r\n\r\n' in received_message:
break
return received_message
async def _handler(self, reader: asyncio, writer: asyncio) -> None:
"""
Хендрел который вызываеться при получении нового соединения.
Функция осуществляет получение данных вызывом
self._reading_message с timeout=1 и отправку результатов пользователю.
:param reader:
:param writer:
:return:
"""
try:
received_message = await asyncio.wait_for(self._reading_message(reader), timeout=1)
# Сохраняем сообщение в файл
write_message_to_file = Handler().change_file(received_message)
if write_message_to_file is True:
writer.write('Ваше сообщение успешно получено!'.encode())
else:
writer.write('Не удалось обработать ваше сообщение!'.encode())
await writer.drain()
writer.close()
await writer.wait_closed()
except asyncio.exceptions.TimeoutError:
msg_error = 'Превышено время ожидания сервера на получение данных от клиента.'
writer.write(msg_error.encode())
async def main(self):
""" Функция запуска сервера"""
server = await asyncio.start_server(client_connected_cb=self._handler,
host=self.ip,
port=self.port,
limit=self.limit)
address = server.sockets[0].getsockname()
print(f'Сервер включен {address}')
async with server:
await server.serve_forever()
class Handler:
def change_file(self, data_to_write):
with open('1.txt', "w") as f:
f.write(data_to_write)
return True
if __name__ == '__main__':
try:
asyncio.run(Server(ip='127.0.0.1', port=8888, limit=128).main())
except KeyboardInterrupt:
print('Сервер остановлен')
except asyncio.exceptions.TimeoutError:
print("Превышено вермя ожидания для получения данный!")
Client:
import asyncio
class Client(object):
"""
Класс опроса сервера проверки
"""
def __init__(self, message):
self.server = '127.0.0.1'
self.port = 8888
self.message = message
async def send_message(self) -> str:
"""
Отправляет запрос на сервер
:return: received_message
"""
# Открываем соединение
reader, writer = await asyncio.open_connection(self.server, self.port)
# Отправляем данные и очиищаем буфер
writer.write(self.message.encode())
await writer.drain()
# дожидаемся ответа и декодируем его
received_message = await reader.read(100)
received_message = received_message.decode()
print(received_message)
# закрываем соеденинения и возвращаем результат
writer.close()
await writer.wait_closed()
return received_message
asyncio.run(Client(message='Прррииивет\r\n\r\n').send_message())
Проблема твоего кода в том что функция которую ты вызываешь ничего не возращает. Используй asyncio и жить станет проще. У тебя не будет блокирующих соединений и не нужно будет запускать потоки, они тебе не нужны.