Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为Blender3D Python脚本应用setblocking(0)时的索引器_Python_Sockets_Tcp_Blender - Fatal编程技术网

为Blender3D Python脚本应用setblocking(0)时的索引器

为Blender3D Python脚本应用setblocking(0)时的索引器,python,sockets,tcp,blender,Python,Sockets,Tcp,Blender,我目前正在运行一个使用Blender3D的脚本,我在Stackoverflow的帮助下从Python2+移植到Python3+。该脚本在欧姆龙PLC(可编程逻辑计算机)和Blender/Python3+之间创建通信。该脚本使用TCP通信来写入和读取PLC的内存。端口后,脚本在Blender中正常运行唯一的问题是它会造成大量延迟,并迫使Blender以6 fps的速度运行 默认情况下,Python套接字是阻塞的。这意味着,当您调用socket.read()时,函数将不会返回,直到您的数据被读取或s

我目前正在运行一个使用Blender3D的脚本,我在Stackoverflow的帮助下从Python2+移植到Python3+。该脚本在欧姆龙PLC(可编程逻辑计算机)和Blender/Python3+之间创建通信。该脚本使用TCP通信来写入和读取PLC的内存。端口后,脚本在Blender中正常运行唯一的问题是它会造成大量延迟,并迫使Blender以6 fps的速度运行

默认情况下,Python套接字是阻塞的。这意味着,当您调用
socket.read()
时,函数将不会返回,直到您的数据被读取或socket上出现错误。i、 e.套接字“阻止”执行,直到操作完成。由于您的代码在
recv()
调用中被阻止,您的游戏将冻结。”

在该链接中,如果您添加
setblocking(0)
setblocking(False)
settimeout(0)
(同样的事情),您将取消TCP通信引起的延迟

为了使其正常工作,我必须尝试包装我的
recv()
调用,但为了避免套接字错误:
BlockingIOError:[WinError 10035]非阻塞套接字操作无法立即完成

我是这样做的:

    def _recieve(self):
    try:
        pr = self.sock.recv(8)
        length = binstr2int( pr[4:8])
        r = pr + self.sock.recv( length)
        #print (' Recv:' + repr(r))
        return r
    except socket.error as err:
        # Any error but "Would block" should cause the socket to close
        if err.errno != errno.EWOULDBLOCK:
            self.sock.close()
            self.sock = None
            return
但是,这并没有解决我的问题,这会产生更多的问题。脚本可以正常运行,但当我使用setblocking(1)时,速度为6fps。但当我打开它时,它会给我一个索引器:

文件“D:\…”,第126行,反汇编格式
asm[b'ICF']=binstr2int(self.rawTcpFrame[16])
索引器:索引超出范围“

这是错误发生的区域,如果我注释掉该行,它只会说错误发生在下一个
self.rawTcpFrame[17]
中,例如:

    def disassembled(self):
    asm = {
           b"header"   : binstr2int( self.rawTcpFrame[ 0: 4] ),
           b'length'   : binstr2int( self.rawTcpFrame[ 4: 8] ),
           b'command' : binstr2int( self.rawTcpFrame[ 8:12] ),
           b'errCode' : binstr2int( self.rawTcpFrame[12:16] ),
    }
    if( asm[b'command'] == 2) :
        asm[ b'ICF'] = binstr2int( self.rawTcpFrame[16])
        asm[ b'RSV'] = binstr2int( self.rawTcpFrame[17])
        asm[ b'GCT'] = binstr2int( self.rawTcpFrame[18])
        asm[ b'DNA'] = binstr2int( self.rawTcpFrame[19])
        asm[ b'DA1'] = binstr2int( self.rawTcpFrame[20])
        asm[ b'DA2'] = binstr2int( self.rawTcpFrame[21])
        asm[ b'SNA'] = binstr2int( self.rawTcpFrame[22])
        asm[ b'SA1'] = binstr2int( self.rawTcpFrame[23])
        asm[ b'SA2'] = binstr2int( self.rawTcpFrame[24])
        asm[ b'SID'] = binstr2int( self.rawTcpFrame[25])
        asm[ b'MRC'] = binstr2int( self.rawTcpFrame[26])
        asm[ b'SRC'] = binstr2int( self.rawTcpFrame[27])
        if self.fromRaw :
            #decode from response
            asm[ b'MRES'] = binstr2int( self.rawTcpFrame[28])
            asm[ b'SRES'] = binstr2int( self.rawTcpFrame[29])
            asm[b'response'] = self.rawTcpFrame[30:]
        else :
            asm[b'cmd'] = self.rawTcpFrame[28:]
    return asm

可以找到整个脚本

您的消息不够长(序列短于17)。您应该测试帧的长度,或者使用
zip
和slice确保您不会尝试调用不存在的索引:

tags = (b'ICF', b'RSV', b'GCT', 
    b'DNA', b'DA1', b'DA2', 
    b'SNA', b'SA1', b'SA2', 
    b'SID', b'MRC', b'SRC')

for tag, data in zip(tags, self.rawTcpFrame[16:]):
    asm[tag] = binstr2int(data)

或者您可以将所有内容包装在
try:…中,但索引器除外:
,并在那里处理过短的帧。

我不确定我是否做对了,但它会导致更多错误。我尝试过将它们包装在try中,但这会与其他内容相混淆:
文件“D:\…”,第177行,在u str_uu中返回b“”。连接([k+b':')+字节(str(asm[k]),'utf-8')+b''表示列表中的k(asm.keys()))))。decode('utf-8')AttributeError:'NoneType'对象没有属性'keys'
这会弄乱程序中的另一行,请检查我问题下的注释。谢谢。您可能应该返回
{}
在您的
除…
子句中,如果您决定捕获错误,而不是使用
zip
/slice方法。在某个地方,您需要决定如何处理丢失的数据,这取决于您决定在何处以及如何处理。但这是另一个问题,值得提出新的问题。请确保您下次做好准备。。。