2016-12-14 8 views
0

с использованием 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: здесь есть образ того, что мои консоли печати, когда я запустить сервер и клиент: enter image description here , как вы можете видеть, что это никогда не напечатав «RECIVED» печать , когда я выйти из блендера игры двигатель, я получаю этот вывод: enter image description here теперь, когда двигатель и сценарий сервера завершены/закрыты/закончены, я получаю распечатанные данные. поэтому 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

+1

Просьба представить [MCVE] (https: // StackOverflow/помощь/mcve). Представленный код не работает (отсутствует импорт), и важная часть отправки и получения файла отсутствует. Если импорт добавлен, этот код правильно отправляет шесть байтов, хотя лучше использовать 'sendall'. Клиент настроен как демон, и основной код сразу же выходит после запуска потока ... убивая его. –

+0

@MarkTolonen sry за недостающий импорт, добавил их к вопросу. Отправляющая и получающая часть не являются проблемой, поэтому я их не выпускал. Даже когда клиент не является деамоном, а сервер использует sendall, результат тот же. – user3416789

+1

Пожалуйста, запустите то, что вы публикуете. Он не воспроизводится. 'PORT' не определен. 'dbpath' не определен. Если я их исправлю, клиент ничего не распечатает и не выйдет, потому что, как я уже говорил, поток запускается как демон, и основной поток немедленно выходит из него, убивая его. Если я удалю поток и просто вызову 'recv', он будет работать, даже если я прокомментирую закрытие на стороне сервера. Обеспечьте воспроизводимую проблему. –

ответ

1

Я наблюдал подобное явление.Похоже, что экземпляр Python не получает каких-либо циклов выполнения из Blender Game Engine (BGE), если не будет вызван контроллер.

Простое решение:

  • Добавить другой датчик Всегда что запускаемое на каждом логическом клеща.
  • Добавить еще один контроллер Python, который ничего не делает, не работает.
  • Подключите датчик к контроллеру.

Я применил это к вашему .blend, как показано на следующем экране.

screen capture showing added sensor and code

Я проверил это, запустив сервер и, кажется, работает нормально.

Cheers, Джим