def receive(self, timeout=30): """ Receive data. :param timeout: time-out, default 30 sec :type timeout: float """ if not self.socket: raise RemoteEndpointNotConnected() ready = select.select([self.socket], [], [], timeout) if ready[0]: try: data = self.socket.recv(self.receive_buffer_size) # TODO: rework logging to have LogRecord with extra=direction # TODO: separate data sent/received from other log records ? self._debug('< {}'.format(data)) except socket.error as serr: if (serr.errno == 10054) or (serr.errno == 10053): self._close_ignoring_exceptions() raise RemoteEndpointDisconnected(serr.errno) else: raise serr if not data: self._close_ignoring_exceptions() raise RemoteEndpointDisconnected() return data else: # don't want to show class name - just tcp address # want same output from any implementation of TCP-connection info = "Timeout (> %.3f sec) on {}".format(timeout, self) raise ConnectionTimeout(info)
def _recv(self): """Receive data.""" if not self._shell_channel: raise RemoteEndpointNotConnected() try: # ensure we will never block in channel.recv() if not self._shell_channel.gettimeout(): self._shell_channel.settimeout( self.await_ready_tick_resolution) data = self._shell_channel.recv(self.receive_buffer_size) except socket.timeout: # don't want to show class name - just ssh address # want same output from any implementation of SshShell-connection info = "Timeout (> {:.3f} sec) on {}".format(self.timeout, self) raise ConnectionTimeout(info) if not data: self._debug("shell ssh channel closed for {}".format(self)) self._close() raise RemoteEndpointDisconnected() return data
def _send(self, data, timeout=1.0): start_time = time.time() nb_bytes_to_send = len(data) nb_bytes_sent = 0 data2send = data while True: if self._shell_channel.send_ready(): chunk_bytes_sent = self._shell_channel.send(data2send) nb_bytes_sent += chunk_bytes_sent else: time.sleep(self.await_ready_tick_resolution) nb_bytes_sent = 0 if nb_bytes_sent >= nb_bytes_to_send: break if time.time() - start_time >= timeout: send_status = '[{} of {} bytes] {}'.format( nb_bytes_sent, nb_bytes_to_send, data) # don't want to show class name - just ssh address # want same output from any implementation of SshShell-connection info = "Timeout (> {:.3f} sec) on {}, sent {}".format( timeout, self, send_status) raise ConnectionTimeout(info) data2send = data[nb_bytes_sent:]