def send(self, connMsg): """Send a command to the server. Server may reply (if reply requested) or may not. @param connMsg: The command to be sent @type connMsg: ConnMsg object""" #str=cPickle.dumps(connMsg,protocol=cPickle.HIGHEST_PROTOCOL) #serialise.Send([str],self.sock) serialise.Send(connMsg.pickle(), self.sock)
def test(self): """Send test data""" a=numpy.array([[1,22,33],[4,55,66]],"i") b=numpy.array([[11,122,133],[14,155,166]],"i") b[1]=a[0] print "Contiguous?",b.iscontiguous(),b serialise.Send(["hello there",10,(1,2,3),{5:2,3:4},a,b],self.sock) print "sent..."
def connectSock(self): self.sock = None while self.sock == None and self.attempts != 0: if self.attempts > 0: self.attempts -= 1 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.sock.connect((self.host, self.port)) print "Connected to Receiver" except: print "Couldn't connect to receiver on %s %d" % (self.host, self.port) self.sock = None time.sleep(1) if self.sock == None: sys.exit(0) serialise.Send(["name", self.prefix + self.shmname], self.sock) print "name sent %s" % (self.prefix + self.shmname) if self.raw: #inform that we'll be sending raw data... print "Sending raw flag" serialise.Send(["raw", "raw", self.prefix + self.shmname], self.sock)
def execute(self, cmd, rt=None, tag=None, data=None): """Cause a command to be executed on the server. cmd is the python string to be exec'd, rt is the name of the variable to be returned if desired, tag is optional, and data is any data that should be sent with the command, and when the cmd is exec'd, data is referred to as "remoteData". e.g. your cmd could be something like: "localArray[:]=remoteData" which would copy the remoteData value(s) into localArray on the server.""" if self.conn != None: if tag == None: tag = self.getTag() lst = ["now", cmd, rt, tag, data] try: serialise.Send(lst, self.conn) except: self.conn = None raise else: tag = None return tag
def execCmd(self, data, sock): """Execute a command. @param data: The command to be executed @type data: ConnMsg instance @param sock: A socket @type sock: socket.socket instance @return: The executed value @rtype: User defined """ #command=data[0] command = data.command tag = data.tag remoteData = data.remoteData self.globals["remoteData"] = remoteData self.globals["sock"] = sock rtval = 0 ## if len(data)>1: ## rtObjects=data[1] ## if type(rtObjects)!=types.ListType: ## rtObjects=[rtObjects] ## else: ## rtObjects=None rtObjects = data.ret d = {} #newly created variables go in here... if self.printmsg: print "Acquiring lock" self.lock.acquire() if self.printmsg: print "Executing", command try: exec command in self.globals, d except Exception, msg: rtval = 1 print "Command Exec failed1:", command, msg print str(sys.exc_info()), str(sys.exc_info()[1].args) #print self.globals if sock != None: try: serialise.Send([ "error", tag, "Command execution failed: %s %s" % (command, msg) ], sock) except: print "Serialise failed in SockConn.execCmd - couldn't send error message"
def execCmd(self, data, sock): """Execute a command. @param data: The command to be executed @type data: ConnMsg instance @param sock: A socket @type sock: socket.socket instance @return: The executed value @rtype: User defined """ #command=data[0] command = data.command tag = data.tag rtval = 0 ## if len(data)>1: ## rtObjects=data[1] ## if type(rtObjects)!=types.ListType: ## rtObjects=[rtObjects] ## else: ## rtObjects=None rtObjects = data.ret d = {} #newly created variables go in here... if self.printmsg: print "INFORMATION Executing", command try: exec command in self.globals, d except Exception, msg: data.retryCnt += 1 txt = "Will retry" if data.retryCnt > data.maxRetry: rtval = 1 txt = "Cancelling" print "ERROR Command Exec failed1:", command, msg #print str(sys.exc_info()),str(sys.exc_info()[1].args) #print self.globals if sock != None: try: serialise.Send([ "error", tag, "Command execution failed (%s): %s %s" % (txt, command, msg) ], sock) except: print "ERROR Serialise failed in SockConn.execCmd - couldn't send error message"
def loop(self): """Waits for data, and sends it over socket.""" #first, open the buffer... self.cumfreq = self.decimate if self.startWithLatest: ret = self.circbuf.getLatest() while self.go: #wait for data to be ready #print "Waiting for data" ret = self.circbuf.getNextFrame(timeout=10, copy=1) if self.debug: if ret == None: print "No data yet %s" % (self.prefix + self.shmname) else: print "Got data %s" % (self.prefix + self.shmname) #if key=="rtcTimeBuf": # ret=b.data[:,0],ret[1],ret[2] #How can I tell if a timeout occurred because rtc is dead/restarted or because its paused/not sending? #First, open the shm in a new array, and look at header. If header is same as existing, don't do anything else. Otherwise, reopen and reinitialise the circular buffer. if ret == None: if self.checkSHM(): #returns 1 on failure... print "Reopening SHM" self.openSHM() ret = self.circbuf.getNextFrame(timeout=10, copy=1) else: #shm still valid - probably timeout occurred, meaning RTC still dead, or just not producing this stream. pass #Check to see if we're lagging behind the RTC - if so, send the latest frame... lw = self.circbuf.lastWritten[0] if lw >= 0: diff = lw - self.circbuf.lastReceived if diff < 0: diff += self.circbuf.nstore[0] if diff > self.circbuf.nstore[0] * .75: print "Sending of %s lagging - skipping %d frames" % ( self.prefix + self.shmname, diff - 1) ret = self.circbuf.get(lw, copy=1) if ret != None: cbfreq = int(self.circbuf.freq[0]) if cbfreq < 1: cbfreq = 1 self.cumfreq += cbfreq self.cumfreq -= self.cumfreq % cbfreq if self.cumfreq >= self.decimate: #so now send the data self.cumfreq = 0 #data,timestamp,frameno=ret #print "got data at %s %s %s"%(str(timestamp),str(data.shape),str(data.dtype.char)) if self.saver != None: if self.raw: self.saver.writeRaw(ret) else: data, ftime, fno = ret self.saver.write(data, ftime, fno) #send the data #print "sending",self.sock if self.sock != None: try: if self.debug: print "Sending %s" % (self.prefix + self.shmname) if self.raw: try: self.sock.sendall(ret) except: print "Error in sendStream with raw stream - sock.sendall failed - couldn't send raw data" raise else: serialise.Send( ["data", self.prefix + self.shmname, ret], self.sock) except: #self.connectSock() print "error in serialise.Send - exiting - finishing sending of %s" % ( self.prefix + self.shmname) self.go = 0 #raise if self.saver != None: self.saver.close()
def readsock(self, sock): """Reads the socket, obtaining 'data'. data.action will be a control word, e.g. 'cmd' If data.action=='now': data.command will be command to be exec'd. data.ret (if present) will be list of things to return. If data.action=='rpt':#repeat command data.command will be command to be exec'd. data.ret (if present) will be list of things to return. If data.action=='cmd':#command to execute during break... data.command will be command to be exec'd. data.ret (if present) will be list of things to return. If data.action=='del':#delete command from regular/cmd list this will be deleted... @param sock: Socket to read @type sock: socket.socket instance """ try: tmp = serialise.ReadMessage(sock.fileno()) except: print "WARNING Connection reset by peer." return -1 if not tmp: return -1 #connection closed. #print "socketdata:",tmp data = ConnObj.ConnMsg(None, None) data.unpickle(tmp) #data=cPickle.loads(data[0])#unpickle a ConnMsg object. action = data.action tag = data.tag print "INFORMATION got data: %s %s %s %s" % (str( data.action), str(data.command), str(data.tag), str(data.ret)) #cmd=data.pop(0) if action == "now": if self.globals == None: self.cmdList.append([data, sock]) else: self.execCmd(data, sock) elif action == "cmd": self.cmdList.append([data, sock]) elif action[:3] == "rpt": freq = 1 if len(action) > 3: freq = int(action[3:]) if freq < 1: freq = 1 self.rptCmdList.append([data, sock, freq, 0]) elif action == "del": remlist = [] #print "Action del:",data,sock for cmd in self.rptCmdList: #print cmd try: if (data.command == "" or data.command == None or cmd[0].command == data.command ) and sock == cmd[1] and (tag == None or cmd[0].tag == tag): #if cmd[:2]==[data,sock]: remlist.append(cmd) except: print "ERROR deleting", data, sock, cmd print data.command for cmd in remlist: print "INFORMATION Deleting action", cmd self.rptCmdList.remove(cmd) while [data, sock] in self.cmdList: print "Deleting action:", [data, sock] self.cmdList.remove([data, sock]) elif action == "add": #prepend data.command to config.postList... print "INFORMATION SockConn - got data action add" if type(data.command) == type(()) and len( data.command) == 2 and type(data.command[0]) == type(""): if type(self.globals) != type(None): print "INFORMATION Adding to config.postList - %s" % data.command[ 0] self.globals["ctrl"].config.postAdd(data.command) print "Added post variable %s to config.postList" % data.command[ 0] else: print "ERROR Cannot add post variable %s to config, SockConn has no globals" % data.command[ 0] else: print "ERROR SockConn - action add not received with non-valid data, should be tuple of (str,data)." else: print action, data serialise.Send(["warning", tag, "data not understood"], sock)
def loop(self): """probably start this in a new thread... listens on the socket, and does stuff depending on what it gets""" while self.go: if self.fsock == -1: break selOut = [] try: rtr, rtw, err = select.select(self.selIn, selOut, self.selIn) except: traceback.print_exc() print "WARNING in select - continuing..." time.sleep(1) rtr = [] rtw = [] err = [] for s in err: #remove from dict, and act on it... self.close(s) for s in rtr: #ready to read the socket if s == self.lsock: #listening socket - new client... print 'INFORMATION Accepting new client...' conn, raddr = s.accept() print "from %s" % str(raddr) self.selIn.append(conn) elif s == sys.stdin: #print "Got from stdin" try: data = s.readline()[:-1] except: data = "Error reading from stdin" #print self.globals try: ft = self.globals["ctrl"].frametime ti = self.globals["ctrl"].thisiter except: ti = 0 ft = 1. if ft == 0: ft = 1. print "INFORMATION At iteration %d, taking %gs per frame (%g fps) on port %s" % ( ti, ft, 1. / ft, str(self.port)) if len(data) > 0: if data[0] == "s": try: txt = "" ctrl = self.globals["ctrl"] scienceList = ctrl.compList dlist = [] for s in scienceList: if hasattr(s, 'strParams') and s not in dlist: dlist.append(s) for i in range(len(s.thisObjList)): txt += s.thisObjList[ i].idstr + ': ' + s.strParams( i) + '\n' txt += 'Iter %d frametime %g (mean %g) batch %d\n%s' % ( ctrl.thisiter, ctrl.frametime, ctrl.meanTiming.sum() / ctrl.thisiter, ctrl.batchno, ctrl.simID) print txt except: traceback.print_exc() elif data[0] == "h": print "HELP: <ret> for iteration number\ns<ret> for science information" else: print data, len(data) elif s == self.fsock: #forward data... (return to client) data = s.recv(1024) length = len(data) if length == 0: self.close(s) else: for sk in self.selIn: if sk != self.lsock and sk != self.fsock: try: sk.sendall(data) except: self.close(sk) else: #readsock or forward data... if self.fsock != None: #forward the data... data = s.recv(1024) if len(data) == 0: self.close(s) else: try: self.fsock.sendall(data) except: serialise.Send( ["warning", None, "couldn't forward data"], s) else: #readsock. #print 'Reading socket...' if self.readsock(s) == -1: #connection closed try: print 'INFORMATION Closing socket %s' % str( s.getpeername()) except: print "INFORMATION Closing socket" self.close(s)
"Command execution failed (%s): %s %s" % (txt, command, msg) ], sock) except: print "ERROR Serialise failed in SockConn.execCmd - couldn't send error message" except: data.retryCnt += 1 txt = "Will retry" if data.retryCnt > data.maxRetry: rtval = 1 txt = "Cancelling" print "ERROR Command exec failed2:", command if sock != None: try: serialise.Send([ "error", tag, "Command execution failed (%s): %s" % (txt, command) ], sock) except: print "ERROR Serialise failed in SockConn.execCmd - couldn't send error message" else: rt = {} #will return rt to the user. l = 0 if rtObjects == None: #return all objects created... rtObjects = d.keys() elif type(rtObjects) not in [types.ListType, types.TupleType]: rtObjects = [rtObjects] for key in rtObjects: if d.has_key(key): rt[key] = d[key] l += 1 elif key not in ["", " "]:
def loop(self): """probably start this in a new thread... listens on the socket, and does stuff depending on what it gets""" while self.go: if self.fsock == -1: break selOut = [] for k in self.writeDict.keys(): if len(self.writeDict[k]) > 0: selOut.append(k) selErr = self.selIn + selOut #print self.selIn,selOut if len(selErr) == 0: if self.verbose: print "No connections any more... will exit" self.go = 0 break try: rtr, rtw, err = select.select(self.selIn, selOut, selErr, self.timeout) except KeyboardInterrupt: print "Keyboard interrupt in SockConn.loop" raise except: print "Error in select" print self.selIn traceback.print_exc() #Remove the offending sockets remlist = [] for s in self.selIn: try: rtr, rtw, err = select.select([s], [], [], 0) except: remlist.append(s) print "Removing %s" % str(remlist) for s in remlist: self.selIn.remove(s) remlist = [] for s in selOut: try: rtr, rtw, err = select.select([], [s], [], 0) except: remlist.append(s) print "Removing %s" % str(remlist) for s in remlist: selOut.remove(s) rtr = [] rtw = [] for s in self.selIn: pass if self.timeout != None and len(rtr) + len(rtw) + len( err) == 0 and self.timeoutFunc != None: self.timeoutFunc() for s in err: #remove from dict, and act on it... try: self.close(s) except: print "sockConn.py - error in self.close" traceback.print_exc() for s in rtr: #ready to read the socket if s == self.lsock: #listening socket - new client... if self.verbose: print 'Accepting new client...' conn, raddr = s.accept() if self.verbose: print "from %s" % str(raddr) self.selIn.append(conn) if self.connectFunc != None: self.connectFunc(conn) elif s == sys.stdin: #print "Got from stdin" try: data = s.readline()[:-1] except: data = "Error reading from stdin" #print self.globals try: ft = self.globals["ctrl"].frametime ti = self.globals["ctrl"].thisiter except: ti = 0 ft = 1. if ft == 0: ft = 1. print "At iteration %d, taking %gs per frame (%g fps)" % ( ti, ft, 1. / ft) #print data,len(data) elif s == self.fsock: #forward data... (return to client) data = s.recv(1024) length = len(data) if length == 0: self.close(s) else: for sk in self.selIn: if sk != self.lsock and sk != self.fsock: try: sk.sendall(data) except: self.close(sk) elif s in self.userSelList: if self.userSelCmd(s) == False: if self.verbose: print "SockConn removing %s" % str(s) try: self.selIn.remove(s) except: pass #print "selIn now %s"%str(self.selIn) try: self.userSelList.remove(s) except: pass else: #readsock or forward data... if self.fsock != None: #forward the data... data = s.recv(1024) if len(data) == 0: self.close(s) else: try: self.fsock.sendall(data) except: serialise.Send( ["warning", None, "couldn't forward data"], s) else: #readsock. #print 'Reading socket...' if self.readsock(s) == -1: #connection closed try: print 'Closing socket %s' % str( s.getpeername()) except: print "Closing socket" self.close(s) for s in rtw: #Now write to sockets that have data waiting to be written... if self.writeDict.has_key(s) and len(self.writeDict[s]) > 0: data = self.writeDict[s].pop(0) if len(data) > 0: #print type(data),s,len(data) #sent=s.send(data) #data=data[sent:]#remove the sent portion... sent = 1 while sent > 0: #repeat while socket still working... #print type(data) try: sent = s.send(data) except: sent = 0 data = data[sent:] #remove the sent portion... if len(data) == 0: if len(self.writeDict[s]) > 0: data = self.writeDict[s].pop(0) if len(data) > 0: #put back unsent data self.writeDict[s].insert(0, data) if self.verbose: print "Loop ended in SockConn.py"