с использованием python 3, я пытаюсь отправить файл с сервера клиенту, как только клиент подключится к серверу, проблема в том, что клиент делает это только с recv когда я закрываю его (когда соединение закрыто)python client recv только при выходе из BGE
Я запускаю клиента в игровом движке blender, клиент работает до тех пор, пока он не получит recv, а затем он просто остановится, пока я не выйду из игрового движка, тогда я может видеть, что консоль получает ожидаемые байты.
из других тем Я читал, что это может быть bco, поскольку recv никогда не заканчивается, поэтому я добавил «\ n \ r» в конец моего bytearray, который отправляет сервер. но все же клиент просто останавливается в recv, пока я не выйду из приложения.
в приведенном ниже коде Я только отправляю первые 6 байтов, это сообщить клиенту размер файла. после этого я намереваюсь отправлять данные файла по тому же соединению.
что я делаю неправильно здесь?
клиент:
import socket
import threading
def TcpConnection():
TCPsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
TCPsocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
server_address = ('localhost', 1338)
TCPsocket.connect(server_address)
print("TCP Socket open!, starting thread!")
ServerResponse = threading.Thread(target=TcpReciveMessageThread,args=(TCPsocket,))
ServerResponse.daemon = True
ServerResponse.start()
def TcpReciveMessageThread(Sock):
print("Tcp thread running!")
size = Sock.recv(6)#Sock.MSG_WAITALL
print("Recived data", size)
Sock.close()
Сервер:
import threading
import socket
import os
def StartTcpSocket():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 1338))
server_socket.listen(10)
while 1:
connection, client_address = server_socket.accept()
Response = threading.Thread(target=StartTcpClientThread,args=(connection,))
Response.daemon = True # thread dies when main thread (only non-daemon thread) exits.
Response.start()
def StartTcpClientThread(socket):
print("Sending data")
length = 42
l1 = ToByts(length)
socket.send(l1)
#loop that sends the file goes here
print("Data sent")
#socket.close()
def ToByts(Size):
byt_res = (Size).to_bytes(4,byteorder='big')
result = bytearray()
for r in byt_res:
result.append(r)
t = bytearray("\r\n","utf-8")
for b in t:
result.append(b)
return result
MessageListener = threading.Thread(target=StartTcpSocket)
MessageListener.daemon = True # thread dies when main thread (only non-daemon thread) exits.
MessageListener.start()
while 1:
pass
, если проблема заключается в том, что клиент не найти конец потока, то, как можно решить эту проблему без закрытия соединение, поскольку я намерен отправить файл по тому же соединению.
Обновление №1: , чтобы уточнить, печать на клиенте, которая говорит «recived», печатается первым, когда я выхожу из ge (клиент закрывается). Цикл, который отправляет файл и возвращает его туда, где не учитывается вопрос, поскольку это не проблема. проблема остается без них, клиент зависает в recv до тех пор, пока он не будет закрыт.
Update # 2: здесь есть образ того, что мои консоли печати, когда я запустить сервер и клиент: , как вы можете видеть, что это никогда не напечатав «RECIVED» печать , когда я выйти из блендера игры двигатель, я получаю этот вывод: теперь, когда двигатель и сценарий сервера завершены/закрыты/закончены, я получаю распечатанные данные. поэтому recv, вероятно, приостанавливает поток до закрытия сокета, почему он это делает? и как я могу получить свои данные (и печать) до закрытия сокета? Это также происходит, если я изложу
ServerResponse.daemon = False
here являются .blend (на MediaFire) клиента, сервер работает на Python 3 (PyPy). Я использую blender 2.78a
Обновление № 3: Я протестировал и проверил, что проблема одинаков для Windows 10 и linux mint. Я также сделал видео, показывающее проблему:
В видео вы можете видеть, как я получаю данные только с сервера, когда я выхожу из блендера ge. После некоторого исследования, которое я ожидал, чтобы подозревать, что проблема связана с потоками python, не очень хорошо работает с bge.
https://www.youtube.com/watch?v=T5l9YGIoDYA
Просьба представить [MCVE] (https: // StackOverflow/помощь/mcve). Представленный код не работает (отсутствует импорт), и важная часть отправки и получения файла отсутствует. Если импорт добавлен, этот код правильно отправляет шесть байтов, хотя лучше использовать 'sendall'. Клиент настроен как демон, и основной код сразу же выходит после запуска потока ... убивая его. –
@MarkTolonen sry за недостающий импорт, добавил их к вопросу. Отправляющая и получающая часть не являются проблемой, поэтому я их не выпускал. Даже когда клиент не является деамоном, а сервер использует sendall, результат тот же. – user3416789
Пожалуйста, запустите то, что вы публикуете. Он не воспроизводится. 'PORT' не определен. 'dbpath' не определен. Если я их исправлю, клиент ничего не распечатает и не выйдет, потому что, как я уже говорил, поток запускается как демон, и основной поток немедленно выходит из него, убивая его. Если я удалю поток и просто вызову 'recv', он будет работать, даже если я прокомментирую закрытие на стороне сервера. Обеспечьте воспроизводимую проблему. –