At first I where assuming that i where doing something wrong in my python, and I posted a stackowerflow question about it. then I started to strip things down, And now I’m almost sure that it is in fact a bug in blender that are giving me these problems.
the bug is that when you create a thread holding a tcp socket, the socket gets locked until bge finish. I’m posting this to make sure that there isn’t anything that i’m missing an that this infact is a bug.
here are my server code:
import threading
import socket
import os
def StartTcpSocket():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 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("
","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
this code is run as a python script outside of blender, it creats a tcp socket and w8th for connections, if a connection is made it sends 6 bytes of data to that connection. it works fine.
here is the client:
import socket
import threading
def TcpConnection():
#TCPsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#TCPsocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
print("starting thread!")
ServerResponse = threading.Thread(target=TcpReciveMessageThread)
ServerResponse.daemon = False # thread dies when main thread (only non-daemon thread) exits.
ServerResponse.start()
def TcpReciveMessageThread():
print("Thread Started")
TCPsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (127.0.0.1, 1338)
TCPsocket.connect(server_address)
print("Tcp thread running!")
size = TCPsocket.recv(6)#Sock.MSG_WAITALL
while len(size) < 6:
size += TCPsocket.recv(6)
print("Recived data", size)
TCPsocket.close()
the client code is running as a module in blender game engine, it run only once when the engine starts, using
client.TcpConnection
the client is suppose to spawn a new thread that creates a socket, connects to the server and receive the 6 bytes of data that the server is sending upon connect.
here is the problem, when the client is started, it gives me the print “print(“Thread Started”)”, but here it gets stuck. when I quit the game engine (using"Esc") the thread resumes and starts printing the final prints to the console.
I have been trying to creat the socket object inside ot the main thread and then pass it to the thread, but the result is still the same (see my stackowerflow thread). From what I can tell I’m doing everything correct, but still the thread won’t run any tcp socket-related actions until the engine is finished (by pressing “Esc”)
Note that the thread is probably starting as a real thread, as the main loop don’t freeze.
Also note that IF the thread is starter using .run() instead of .start() everything is working. This isbco .run() don’t spawn a real thread but runs the code inside of the mainloop instead.
and finally note that the daemon status of the thread doesn’t matter, the result are always the same.
If i run this in a python console, everything is working as expected.
so now are I’m doing anything wrong or are this a bug in blender?
I also found abug reportof something similar, but it is closed as invalid.