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 send(self, data, timeout=1): """ Send data via SshShell connection. :param data: data :type data: bytes :param timeout: max time to spend on sending all data, default 1 sec :type timeout: float """ if not self._shell_channel: raise RemoteEndpointNotConnected() assert timeout > 0.0 try: self._send(data, timeout) except socket.error as serr: if "Socket is closed" in str(serr): self._close() info = "{} during send msg '{}'".format(serr, data) raise RemoteEndpointDisconnected('Socket error: ' + info) else: raise # let any other error be visible
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