Configuration

Stream.connect(uri, non_blocking=False, send_buffer_size=1460, receive_buffer_size=1460)

Connects to a listening stream referenced by the given URI. The URI specifies the protocol, address, port, and options associated with the stream. The Stream API uses the protocol to load a protocol-specific driver.

URI examples:

tcpip://remotehost:17000                        - connect to remote host on port 17000 using TCP/IP
shmem://mymemory:1?bufsize=8192                 - connect via an 8K shared memory buffer
pipe:mypipe?bufsize=4096                        - connect via a 4K named pipe
i2c://localhost:0?baud='100000';address='0x48'  - connect via I2C at a baud rate of 100000

If the non_blocking flag is set to False, then this function will block until the connection is made. If the non_blocking flag is set to True, then this function will not block. If the connection is made then True (1) is returned. If the connection cannot be completed immediately, then False (0) is returned. In this case, the connection may be completed using poll with the PollFlag.CONNECT flag. If an error occurs then an exception is raised.

Parameters
  • uri (string) – A URI indicating the listening stream to which to connect.

  • non_blocking (boolean) – Set to True (1) to make the client connection non-blocking.

  • send_buffer_size (int) – The size of the buffer to use for sending data over the stream, in bytes

  • receive_buffer_size (int) – The size of the buffer to use for receiving data over the stream, in bytes

Raises

StreamError – On a negative return code. A suitable error message may be retrieved using get_error_message.

Returns

True if connected; False if connection in progress.

Return type

bool

Example

>>> from quanser.communications import Stream
>>> stream = Stream()
>>> try:
>>>    is_connected = stream.connect("tcpip://localhost:5039", False, 64, 64)
>>>    # ...
...
>>>    stream.shutdown()
>>>    stream.close()
>>> except:
>>>    # An error occurred
Stream.listen(uri, non_blocking=False)

Establishes a server stream which listens on the given URI. The URI specifies the protocol, address, port and options associated with the server stream. The Stream API uses the protocol to load a protocol-specific driver. For example:

tcpip://localhost:17000 - listen on port 17000 using TCP/IP shmem://mymemory:1?bufsize=8192 - listen via shared memory buffer. Use 8K buffers by default. pipe:mypipe?bufsize=4096 - listen via a named pipe. Use 4K buffers for the pipe.

Parameters
  • uri (string) – A URI indicating the stream on which to listen.

  • non_blocking (bool) – Set to True (1) to prevent accept calls from blocking.

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

>>> from quanser.communications import Stream
>>> stream = Stream()
>>> stream.listen("tcpip://localhost:5039", False)
>>> # ...
...
>>> stream.shutdown()
>>> stream.close()
Stream.accept(send_buffer_size=1460, receive_buffer_size=1460)

Accepts a connection to a listening communication stream by a client. The client connects using connect.

If listen was called with non_blocking set to False, then this call will block until a client connects. The client stream returned will also be a blocking stream.

If listen was called with non_blocking set to True, then this call will not block. If there is no pending client connection, then it will raise -ErrorCode.WOULD_BLOCK. The poll function may be used with PollFlag.ACCEPT to determine when a client connection is pending. In this case, the client stream returned will also be a non-blocking stream.

On POSIX systems this function should be interruptible by a signal so that arrival of a signal will cause a -ErrorCode.INTERRUPTED error to be returned.

Parameters
  • send_buffer_size (int) – The size of the buffer to use for sending data over the stream, in bytes

  • receive_buffer_size (int) – The size of the buffer to use for receiving data over the stream, in bytes

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Returns

The client stream or None if there is no client stream.

Return type

Stream or None

Example

>>> from quanser.communications import Stream
>>> uri = "tcpip://localhost:5000"
>>> send_buffer_size = 64
>>> receive_buffer_size = 64
>>> server_stream = Stream()
>>> client_stream = Stream()
>>> server_stream.listen(uri, False)
>>> client_stream.connect(uri, False, send_buffer_size, receive_buffer_size)
>>> client_connection = server_stream.accept(send_buffer_size, receive_buffer_size)
>>> # ...
...
>>> client_connection.shutdown()
>>> client_stream.shutdown()
>>> client_connection.close()
>>> client_stream.close()
>>> server_stream.close()
Stream.poll(timeout, flags)

Polls the stream to determine whether it is possible to send or receive or accept a connection without blocking. The flags argument determines the conditions for which to check. The return value indicates the conditions which occurred. This function returns after the given timeout with a value of 0 if none of the conditions occurs. If an error occurs, then it returns a negative error code. The function will return before the timeout if at least one of the conditions occurs prior to the timeout.

Note that this function may return zero even if the timeout has not occurred, even when the timeout is infinite. This special case occurs when the shutdown method has been called on the stream. Once the stream is shut down, the timeout may be limited to the close timeout associated with the stream (for shmem, for instance). Hence, the stream may timeout in this case and return 0 before the specified timeout, even if the timeout is infinite.

Parameters
  • timeout (Timeout) – A timeout structure, or None for an infinite timeout.

  • flags (int) – A bit mask indicating the conditions for which to check. Valid flags are: PollFlag.RECEIVE = on a listening stream, check for connections pending from clients. On a client stream, check whether there is any data available to receive. PollFlag.SEND = not valid on a listening stream. On a client stream, check whether there is space in the stream buffer to store any data. PollFlag.FLUSH` = not valid on a listening stream. On a client stream, check whether it is possible to flush any more data without blocking. ``PollFlag.ACCEPT = not valid on a client stream. On a listening stream, check whether there is a pending client connection. PollFlag.CONNECT = not valid on a listening stream. On a client stream, check whether the connection has completed.

Returns

A bit mask containing the conditions which were satisfied. It has the same definition as the flags argument. If none of the specified conditions occurs before the timeout, then 0 is returned.

Return type

int

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

Poll a stream

>>> from quanser.common import Timeout
>>> from quanser.communications import Stream, PollFlag
>>> timeout = Timeout(3)
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   result = stream.poll(timeout, PollFlag.SEND | PollFlag.RECEIVE)
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()
Stream.shutdown()

Shuts down send and/or receives in preparation for closing the stream. Note that close still needs to be called to free resources.

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

>>> from quanser.communications import Stream
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()
Stream.close()

Closes the stream. All resources associated with the stream are freed.

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

>>> from quanser.communications import Stream
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()
static Stream.close_all()

Closes all streams established using stream_listen, stream_connect or stream_accept.

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

>>> from quanser.communications import Stream
>>> uri = "tcpip://localhost:5000"
>>> server = Stream()
>>> client = Stream()
>>> server.listen(uri, False)
>>> client.connect(uri, False, 64, 64)
>>> # ...
...
>>> Stream.close_all()
Stream.get_swap_bytes()

Returns whether the functions that send and receive shorts, t_utf16_chars, t_utf32_chars, integers, longs, singles, doubles or arrays of them, swap the bytes in the individual values.

Byte swapping is only necessary when communicating between processors that use a different endianness. For example, Intel processors are little endian (LSB first) while Motorola processors tend to be big endian (MSB first). By default, no byte swapping takes place. Whether byte swapping is necessary may be determined simply by sending 0x1234 as a short and seeing if it arrives as the same number or 0x3421.

This function returns True (1) if byte swapping is enabled and False (0) otherwise. If the stream is invalid an exception is raised.

Returns

state – Returns True (1) if byte swapping is enabled and False (0) otherwise.

Return type

boolean

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

Determine if the given stream swaps bytes.

>>> from array import array
>>> from quanser.communications import Stream
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   swapping = stream.get_swap_bytes()
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()
Stream.set_swap_bytes(swap)

Configures whether the functions that send and receive shorts, t_utf16_chars, t_utf32_chars, integers, longs, singles, doubles or arrays of them, should swap the bytes in the individual values.

Byte swapping is only necessary when communicating between processors that use a different endianness. For example, Intel processors are little endian (LSB first) while Motorola processors tend to be big endian (MSB first). By default, no byte swapping takes place. Whether byte swapping is necessary may be determined simply by sending 0x1234 as a short and seeing if it arrives as the same number or 0x3421.

Pass True (1) to enable byte swapping and False (0) to disable it. If the stream is invalid an exception is raised.

Note that set_swap_bytes and set_byte_order override each other. The function most recently called will determine whether byte swapping occurs.

Parameters

state (boolean) – Set to True (1) to enable byte swapping, and False (0) to disable byte swapping.

Returns

old_state – Returns the previous byte swapping state. A return value of False (0) indicates that byte swapping was not enabled prior to the call, and a return value of True (1) indicates that byte swapping was enabled prior to the call.

Return type

boolean

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

Configure the given stream to swap bytes in multi-byte data types.

>>> from array import array
>>> from quanser.communications import Stream
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   stream.set_swap_bytes(True)
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()
Stream.set_byte_order(order)

Configures whether the functions that send and receive shorts, t_utf16_chars, t_utf32_chars, integers, longs, singles, doubles or arrays of them, should swap the bytes in the individual values.

Byte swapping is only necessary when communicating between processors that use a different endianness. For example, Intel processors are little endian (LSB first) while Motorola processors tend to be big endian (MSB first). By default, no byte swapping takes place. This function compares the byte order given to the native byte ordering of the platform running the code and tells the stream to swap bytes if the byte orders are different.

Note that set_swap_bytes and set_byte_order override each other. The function most recently called will determine whether byte swapping occurs.

Parameters

order (ByteOrder) – The byte order to use from the ByteOrder enumeration.

Returns

result – Returns 0 on success. Otherwise an exception is raised.

Return type

int

Raises

StreamError – On non-zero return code. A suitable error message may be retrieved using get_error_message.

Example

Configure the given stream to use little-endian byte order for multi-byte data types.

>>> from array import array
>>> from quanser.communications import Stream, ByteOrder
>>> stream = Stream()
>>> stream.connect("tcpip://localhost:5000", False, 64, 64)
>>> try:
>>>   stream.set_byte_order(ByteOrder.LITTLE_ENDIAN)
>>>   # ...
...
>>>   stream.shutdown()
>>> finally:
>>>   stream.close()