Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opening TCP/IP connection to invalid IP blocks forever #88

Open
iliis opened this issue Sep 23, 2016 · 4 comments
Open

opening TCP/IP connection to invalid IP blocks forever #88

iliis opened this issue Sep 23, 2016 · 4 comments

Comments

@iliis
Copy link

iliis commented Sep 23, 2016

While resource_manager.open_resource('TCPIP::127.0.0.1') immediately raises a ConnectionRefusedError, connecting to an IP that doesn't exist (e.g. doing resource_manager.open_resource('TCPIP::192.255.255.42') or something) will block forever.

This is an issue in https://github.com/hgrecco/pyvisa-py/blob/master/pyvisa-py/protocols/rpc.py#L339: socket.connect() blocks as the socket is in blocking mode. Adding for example socket.settimeout(5) immediately before this puts the socket into timeout mode and the connect() will timeout after five seconds.

I haven't checked, but as long as the socket is in blocking mode other operations might behave similarly and block forever (or timeout after a very long time).

I would suggest to at least set some default timeout. Pyvisa actually has a parameter for that in open_resource() called open_timeout (see http://pyvisa.readthedocs.io/en/stable/api/resourcemanager.html#pyvisa.highlevel.ResourceManager.open_resource).

See also https://docs.python.org/3/library/socket.html#socket-timeouts

@skrchnavy
Copy link
Contributor

Different approach implemented in TCPIP INSTR and TPCIP SOCKET.

  • TCPIP INSTR:
    def connect(self):
        logger.debug('RawTCPClient: connecting to socket at (%s, %s)', self.host, self.port)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((self.host, self.port))
  • TPCIP SOCKET:
        self.interface = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.interface.setblocking(0)

        try:
            self.interface.connect_ex((self.parsed.host_address, int(self.parsed.port)))
        except Exception as e:
            raise Exception("could not create socket: %s" % e)

None is correct, handling of connect timeout is not provided. In SOCKET mode, also there is no check, if connect was succesful.

bors bot added a commit that referenced this issue Nov 28, 2017
115: TCPIP SOCKET improvements r=skrchnavy a=skrchnavy

* Connect uses open_timeout parameter to be timeouted (#88)
* Refactored read operation with improved timeout handling
* Read Uses bytearray and bytes instead of string - inspired by #50 
* Calculation of return data in read uses indexes
* Renamed some variables for better readability.
@skrchnavy
Copy link
Contributor

#115 implemented connect timeout in TCPIP SOCKET session.
@iliis Is same expected also in TCPIP INSTR session? (I don't have access to such device so can't test).

@iliis
Copy link
Author

iliis commented Nov 29, 2017

@skrchnavy Uhm, I'm not sure. What's the difference? I'm sending GPIB commands to the device via TCP, so its INSTR?
Does it actually matter? Connecting should never block indefinitely, so I would say, yes, the same behaviour is expected in both cases.
And you don't need a device to test the timeout-behaviour itself for a non-existing devce ;) If you tell me what to test I can do that too.

@skrchnavy
Copy link
Contributor

@iliis :

There are 2 types of devices:

  • TCPIP0::1.2.3.4::999::SOCKET
    Raw TCP/IP access to port 999 at the specified IP address.
  • TCPIP::dev.company.com::INSTR
    A TCP/IP device using VXI-11 or LXI located at the specified address. This uses the default LAN Device Name of inst0.
    when TCPIP::1.2.3.4 is asked then it is equivalent to TCPIP::1.2.3.4::INSTR.

Device shall not block in case, when timeout != VI_TMO_INFINITE (http://zone.ni.com/reference/en-XX/help/370131S-01/ni-visa/vi_attr_tmo_value/).
But handling in both cases is different, SOCKET only initializes connection but INSTR is more complex protocol and it communicates during open resource phase.

Anyway I have INSTR changes in progress. Do you have access to a device for testing?

bors bot added a commit that referenced this issue Feb 27, 2018
120: TCPIP INSTR Session / RPC timeout handling improvements r=MatthieuDartiailh a=skrchnavy

* `rpc` module changes:
  * updated to use timeout and fragmentation size in recv and write operations
  * fragmentation support in write operation
  * connect is timeouted based on timeout
  * 'select' moved to `_sendrecord` and `_recvrecord` functions
* `tcpip` module:
 * open_timeout passed to rpc via vxi11

Related to #88
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants