2016-12-14 12 views
0

python 3を使用して、クライアントからサーバにファイルを送信しようとしています。問題は、クライアントがrecv閉じるとき(接続が閉じられているとき)Pythonクライアントrecv BGE内で終了時に受信する

私はクライアントをブレンダーゲームエンジンで実行しています。クライアントはrecvになるまで実行していますが、ゲームエンジンを終了するまで停止しますコンソールが予想されるバイト数を受信して​​いることがわかります。

他のスレッドから私はこれがbcoかもしれないことを知っていますrecvは決して終わらないので、サーバーが送信している私のbytearrayの最後に「\ n \ r」を追加しました。しかし、依然としてクライアントはアプリケーションを終了するまで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: 明確にするために、geを終了すると(クライアントが終了している)、「recived」と言われるクライアントの印刷が最初に印刷されます。ファイルを送信し、問題のない場所に質問を出さないループです。それでも問題が発生しても、クライアントは終了するまでrecvでフリーズします。あなたは、私がブレンダーのゲームを終了すると、それは「Recived」印刷 を印刷することはありません見ることができるよう enter image description here

更新#2:ここ は、私は、サーバーとクライアントを実行したときに、私のコンソールが印刷されているものの画像ですエンジン、私はこの出力を得ます: enter image description here 今、エンジンとサーバーのスクリプトが終了/終了/終了すると、データが印刷されます。そのため、recvはおそらくソケットが閉じられるまでスレッドを一時停止しています。なぜこれをやっていますか?ソケットが閉じる前に私のデータ(およびプリント)を取得するにはどうすればいいですか?私は

ServerResponse.daemon = False 

hereを設定した場合にも、クライアントの.blendファイル(MediaFireを上)、パイソン3(pypy)上で動作しているサーバーです行われます。私はブレンダーを使用しています。2.78a

更新#3: 私はWindows 10とLinux mintで問題が同じであることをテストし、検証しました。私はまた問題を示すビデオを作った:

ビデオでは、私がblender geを終了するときに私がサーバからのデータをどのように受け取るかを見ることができます。いくつかの研究の後、私は問題がpythonのスレッドに関連していると疑問に思ってbgeでうまくいきません。

https://www.youtube.com/watch?v=T5l9YGIoDYA

+1

[MCVE](https:// stackoverflow/help/mcve)を入力してください。提示されたコードは実行可能ではなく(インポートがありません)、ファイルの送受信の重要な部分が欠落しています。インポートが追加されている場合、このコードは6バイトを正しく送信しますが、 'sendall'が使いやすくなります。クライアントはデーモンとして設定され、メインコードはスレッドを起動した後にただちに終了し、それを強制終了します。 –

+0

@ MarkTolonenは欠落しているインポートを尋ね、質問に追加しました。送信側と受信側の部分は問題ではないので、私はそれらを除外しました。クライアントがdeamonではなく、サーバーがsendallを使用している場合でも、結果は同じです。 – user3416789

+1

あなたの投稿を実行してください。再現性がありません。 'PORT'は定義されていません。 'dbpath'は定義されていません。私がそれらを修正すれば、クライアントは何も印刷せずに終了します。なぜなら、前に述べたように、スレッドはデーモンとして起動し、メインスレッドはすぐに終了して終了するからです。スレッドを削除して 'recv'を呼び出すだけで、サーバ側でcloseをコメントアウトしても機能します。再現性のある問題を提供する。 –

答えて

1

私は同様の現象を観察した。コントローラが呼び出されない限り、PythonインスタンスはBlender Game Engine(BGE)から実行サイクルを受け取らないようです。

簡単な解決策は以下のとおりです。

  • は、すべての論理ティックに解雇された別常にセンサーを追加します。
  • 何もしないノーオペレーションのPythonコントローラを追加してください。
  • センサーをコントローラーに接続します。

次のスクリーンキャプチャのように、これを.blendに適用しました。

screen capture showing added sensor and code

私はあなたのサーバーを実行して、それをテストし、OKに動作するようです。

乾杯、ジム

関連する問題