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」印刷 を印刷することはありません見ることができるよう :
更新#2:ここ は、私は、サーバーとクライアントを実行したときに、私のコンソールが印刷されているものの画像ですエンジン、私はこの出力を得ます: 今、エンジンとサーバーのスクリプトが終了/終了/終了すると、データが印刷されます。そのため、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
[MCVE](https:// stackoverflow/help/mcve)を入力してください。提示されたコードは実行可能ではなく(インポートがありません)、ファイルの送受信の重要な部分が欠落しています。インポートが追加されている場合、このコードは6バイトを正しく送信しますが、 'sendall'が使いやすくなります。クライアントはデーモンとして設定され、メインコードはスレッドを起動した後にただちに終了し、それを強制終了します。 –
@ MarkTolonenは欠落しているインポートを尋ね、質問に追加しました。送信側と受信側の部分は問題ではないので、私はそれらを除外しました。クライアントがdeamonではなく、サーバーがsendallを使用している場合でも、結果は同じです。 – user3416789
あなたの投稿を実行してください。再現性がありません。 'PORT'は定義されていません。 'dbpath'は定義されていません。私がそれらを修正すれば、クライアントは何も印刷せずに終了します。なぜなら、前に述べたように、スレッドはデーモンとして起動し、メインスレッドはすぐに終了して終了するからです。スレッドを削除して 'recv'を呼び出すだけで、サーバ側でcloseをコメントアウトしても機能します。再現性のある問題を提供する。 –