def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ try: self.endpoint_id = endpoint_id self.dest_address = (dest_addr, dest_port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() except TransportInitError as tie: rospyerr("Unable to initiate TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception as e: #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) # FATAL: no reconnection as error is unknown self.done = True if self.socket: try: self.socket.shutdown(socket.SHUT_RDWR) except: pass finally: self.socket.close() self.socket = None raise TransportInitError(str(e)) #re-raise i/o error
def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ try: self.endpoint_id = endpoint_id self.dest_address = (dest_addr, dest_port) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s logdebug('connecting to ' + str(dest_addr) + ' ' + str(dest_port)) self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() self.local_endpoint = self.socket.getsockname() self.remote_endpoint = (dest_addr, dest_port) except TransportInitError as tie: rospyerr( "Unable to initiate TCP/IP socket to %s:%s (%s): %s" % (dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception as e: #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn( "Unknown error initiating TCP/IP socket to %s:%s (%s): %s" % (dest_addr, dest_port, endpoint_id, traceback.format_exc())) # FATAL: no reconnection as error is unknown self.close() raise TransportInitError(str(e)) #re-raise i/o error
def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ # first make sure that if ROS_HOSTNAME=localhost, we will not attempt # to connect to anything other than localhost if ("ROS_HOSTNAME" in os.environ) and (os.environ["ROS_HOSTNAME"] == "localhost"): if not rosgraph.network.is_local_address(dest_addr): msg = "attempted to connect to non-local host [%s] from a node launched with ROS_HOSTNAME=localhost" % (dest_addr) logwarn(msg) self.close() raise TransportInitError(msg) # bubble up # now we can proceed with trying to connect. try: self.endpoint_id = endpoint_id self.dest_address = (dest_addr, dest_port) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s logdebug('connecting to ' + str(dest_addr)+ ' ' + str(dest_port)) self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() self.local_endpoint = self.socket.getsockname() self.remote_endpoint = (dest_addr, dest_port) except TransportInitError as tie: rospyerr("Unable to initiate TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception as e: #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) # check for error type and reason. On unknown errors the socket will be closed # to avoid reconnection and error reproduction if not isinstance(e, socket.error): # FATAL: no reconnection as error is unknown self.close() elif not isinstance(e, socket.timeout) and e.errno not in [ errno.ENETDOWN, errno.ENETUNREACH, errno.ENETRESET, errno.ECONNABORTED, errno.ETIMEDOUT, errno.EHOSTDOWN, errno.EHOSTUNREACH]: # reconnect in follow cases, otherwise close the socket: # 1. socket.timeout: on timeouts caused by delays on wireless links # 2. ENETDOWN (100), ENETUNREACH (101), ENETRESET (102), ECONNABORTED (103): # while using ROS_HOSTNAME ros binds to a specific interface. Theses errors # are thrown on interface shutdown e.g. on reconnection in LTE networks # 3. ETIMEDOUT (110): same like 1. (for completeness) # 4. EHOSTDOWN (112), EHOSTUNREACH (113): while network and/or DNS-server is not reachable # # no reconnection as error is not 1.-4. self.close() raise TransportInitError(str(e)) #re-raise i/o error
def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ # first make sure that if ROS_HOSTNAME=localhost, we will not attempt # to connect to anything other than localhost if ("ROS_HOSTNAME" in os.environ) and (os.environ["ROS_HOSTNAME"] == "localhost"): if not rosgraph.network.is_local_address(dest_addr): msg = "attempted to connect to non-local host [%s] from a node launched with ROS_HOSTNAME=localhost" % (dest_addr) logwarn(msg) self.close() raise TransportInitError(msg) # bubble up # now we can proceed with trying to connect. try: self.endpoint_id = endpoint_id self.dest_address = (dest_addr, dest_port) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s logdebug('connecting to ' + str(dest_addr)+ ' ' + str(dest_port)) self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() self.local_endpoint = self.socket.getsockname() self.remote_endpoint = (dest_addr, dest_port) except TransportInitError as tie: rospyerr("Unable to initiate TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception as e: #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) # check for error type and reason. On unknown errors the socket will be closed # to avoid reconnection and error reproduction if not isinstance(e, socket.error): # FATAL: no reconnection as error is unknown self.close() elif not isinstance(e, socket.timeout) and e.errno not in [100, 101, 102, 103, 110, 112, 113]: # reconnect in follow cases, otherwise close the socket: # 1. socket.timeout: on timeouts caused by delays on wireless links # 2. ENETDOWN (100), ENETUNREACH (101), ENETRESET (102), ECONNABORTED (103): # while using ROS_HOSTNAME ros binds to a specific interface. Theses errors # are thrown on interface shutdown e.g. on reconnection in LTE networks # 3. ETIMEDOUT (110): same like 1. (for completeness) # 4. EHOSTDOWN (112), EHOSTUNREACH (113): while network and/or DNS-server is not reachable # # no reconnection as error is not 1.-4. self.close() raise TransportInitError(str(e)) #re-raise i/o error
def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ # first make sure that if ROS_HOSTNAME=localhost, we will not attempt # to connect to anything other than localhost if ("ROS_HOSTNAME" in os.environ) and (os.environ["ROS_HOSTNAME"] == "localhost"): if not rosgraph.network.is_local_address(dest_addr): msg = "attempted to connect to non-local host [%s] from a node launched with ROS_HOSTNAME=localhost" % (dest_addr) logwarn(msg) self.close() raise TransportInitError(msg) # bubble up # now we can proceed with trying to connect. try: self.endpoint_id = endpoint_id self.dest_address = (dest_addr, dest_port) if rosgraph.network.use_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) else: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s logdebug('connecting to ' + str(dest_addr)+ ' ' + str(dest_port)) self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() self.local_endpoint = self.socket.getsockname() self.remote_endpoint = (dest_addr, dest_port) except TransportInitError as tie: rospyerr("Unable to initiate TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception as e: #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, traceback.format_exc())) # FATAL: no reconnection as error is unknown self.close() raise TransportInitError(str(e)) #re-raise i/o error
class TCPROSTransport(Transport): """ Generic implementation of TCPROS exchange routines for both topics and services """ transport_type = 'TCPROS' def __init__(self, protocol, name, header=None): """ ctor @param name str: identifier @param protocol TCPROSTransportProtocol protocol implementation @param header dict: (optional) handshake header if transport handshake header was already read off of transport. @raise TransportInitError if transport cannot be initialized according to arguments """ super(TCPROSTransport, self).__init__(protocol.direction, name=name) if not name: raise TransportInitError( "Unable to initialize transport: name is not set") self.protocol = protocol self.socket = None self.endpoint_id = 'unknown' self.read_buff = cStringIO.StringIO() self.write_buff = cStringIO.StringIO() self.header = header # #1852 have to hold onto latched messages on subscriber side self.is_latched = False self.latch = None # these fields are actually set by the remote # publisher/service. they are set for tools that connect # without knowing the actual field name self.md5sum = None self.type = None def set_socket(self, sock, endpoint_id): """ Set the socket for this transport @param sock: socket @type sock: socket.socket @param endpoint_id: identifier for connection endpoint @type endpoint_id: str @raise TransportInitError: if socket has already been set """ if self.socket is not None: raise TransportInitError("socket already initialized") self.socket = sock self.endpoint_id = endpoint_id def connect(self, dest_addr, dest_port, endpoint_id, timeout=None): """ Establish TCP connection to the specified address/port. connect() always calls L{write_header()} and L{read_header()} after the connection is made @param dest_addr: destination IP address @type dest_addr: str @param dest_port: destination port @type dest_port: int @param endpoint_id: string identifier for connection (for statistics) @type endpoint_id: str @param timeout: (optional keyword) timeout in seconds @type timeout: float @raise TransportInitError: if unable to create connection """ try: self.endpoint_id = endpoint_id s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if _is_use_tcp_keepalive(): # OSX (among others) does not define these options if hasattr(socket, 'TCP_KEEPCNT') and \ hasattr(socket, 'TCP_KEEPIDLE') and \ hasattr(socket, 'TCP_KEEPINTVL'): # turn on KEEPALIVE s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # - # keepalive failures before actual connection failure s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9) # - timeout before starting KEEPALIVE process s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 60) # - interval to send KEEPALIVE after IDLE timeout s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 10) if timeout is not None: s.settimeout(timeout) self.socket = s self.socket.connect((dest_addr, dest_port)) self.write_header() self.read_header() except TransportInitError, tie: rospyerr( "Unable to initiate TCP/IP socket to %s:%s (%s): %s" % (dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise except Exception, e: self.done = True if self.socket: self.socket.close() self.socket = None #logerr("Unknown error initiating TCP/IP socket to %s:%s (%s): %s"%(dest_addr, dest_port, endpoint_id, str(e))) rospywarn( "Unknown error initiating TCP/IP socket to %s:%s (%s): %s" % (dest_addr, dest_port, endpoint_id, traceback.format_exc())) raise TransportInitError(str(e)) #re-raise i/o error