title: IndexError when applying setblocking(0) for a Blender3D Python script
body: <p>I'm currently running a script with Blender3D I ported from Python 2+ to Python 3+ with the help of someone from Stackoverflow. The script creates communication between a OMRON PLC (Programmable logic computer) and Blender/Python3+. The script uses TCP communication to write and read the PLC's memory. After the port the script ran properly in Blender the only problem it creates a massive amount of lag and forces Blender to run at 6 fps.</p>
  
  <blockquote>
    <p>Python sockets are blocking by default. What that means is that when you call <code>socket.read()</code> the function will not return until your data has been read or there is an error on the socket. i.e. The socket "blocks" execution until the operation has completed. Because your code gets blocked in the <code>recv()</code> call, your game freezes." <a href="http://blenderartists.org/forum/showthread.php?281324-Running-Game-Engine-while-reading-data-wirelessly" rel="nofollow">LINK</a></p>
  </blockquote>
  
  <p>In the link there is said that if you add <code>setblocking(0)</code> or <code>setblocking(False)</code> or <code>settimeout(0)</code> (All the same thing), you will cancel the delay that is caused by the TCP communication.</p>
  
  <p>In order to make it work I had to wrap my <code>recv()</code> call in a try, except in order to avoid a socket error: <code>BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately</code>. </p>
  
  <p>I've done it like this:</p>
  
  <pre><code>    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
  </code></pre>
  
  <p>However this didn't solve my problem, this creates more problems. The script will run fine but at 6fps when I have setblocking(1). But when I turn it on it gives me a Indexerror:</p>
  
  <p><code>File "D:\...", line 126, in disassembled
      asm[ b'ICF'] = binstr2int( self.rawTcpFrame[16])
  IndexError: index out of range'</code></p>
  
  <p>This is the area where the error occurs, if I comment out the line it will just say the error occurs in the next <code>self.rawTcpFrame[17]</code> for example:</p>
  
  <pre><code>    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
  </code></pre>
  
  <p>The entire script can be found <a href="https://www.dropbox.com/s/jtlixga6ogoniyi/OmronFINS_Communicatie_Script_Py34_SO.py" rel="nofollow">here.</a></p>