python客户端recv仅在BGE

时间:2016-12-14 07:52:47

标签: python-3.x sockets tcp freeze recv

使用python 3,我试图在客户端连接到服务器后立即将文件从服务器发送到客户端,问题是客户端只在我关闭它时才从recv继续(当连接已关闭)

我在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直到它关闭。

更新#2: 这是我运行服务器和客户端时我的控制台正在打印的图像: enter image description here 正如你所看到的,它永远不会打印出#34; Recived"打印 当我退出搅拌机游戏引擎时,我得到这个输出: enter image description here 现在,当引擎和服务器脚本退出/关闭/完成时,我会打印数据。所以recv可能暂停线程直到套接字关闭,为什么这样做呢?如何在套接字关闭之前获取我的数据(和打印)?如果我设置

,也会发生这种情况
ServerResponse.daemon = False 

here是客户端的.blend(在mediafire上),服务器在python 3(pypy)上运行。我使用的是搅拌机2.78a

更新#3: 我测试并验证了windows 10和linux mint的问题是一样的。我还制作了一个显示问题的视频:

在视频中,您可以看到我退出blender ge时如何仅从服务器接收数据。经过一番研究后,我不得不怀疑这个问题与python线程有关,并没有与bge配合得很好。

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

1 个答案:

答案 0 :(得分:1)

我观察到类似的现象。除非调用控制器,否则看起来Python实例不会从Blender游戏引擎(BGE)接收任何执行周期。

一个简单的解决方案是:

  • 在每个逻辑刻度线上添加另一个始终传感器。
  • 添加另一个无效的Python控制器,一个无操作。
  • 将传感器挂在控制器上。

我将此应用于您的.blend,如以下截屏所示。

screen capture showing added sensor and code

我通过运行你的服务器测试它,它似乎工作正常。

干杯,吉姆