Asynchronous Read and Write Operations over UDP

This section provides details and examples exploring asynchronous read and write operations with a UDP object.

Functions and Properties

These functions are associated with reading and writing text asynchronously:

FunctionPurpose
fprintfWrite text to a server.
readasyncAsynchronously read bytes from a server.
stopasyncStop an asynchronous read or write operation.

These properties are associated with reading and writing text asynchronously:

PropertyPurpose
BytesAvailableIndicates the number of bytes available in the input buffer.
TransferStatusIndicates what type of asynchronous operation is in progress.
ReadAsyncModeIndicates whether data is read continuously in the background or whether you must call the readasync function to read data asynchronously.

Additionally, you can use all the callback properties during asynchronous read and write operations.

Note

To get a list of options you can use on a function, press the Tab key after entering a function on the MATLAB® command line. The list expands, and you can scroll to choose a property or value. For information about using this advanced tab completion feature, see Using Tab Completion for Functions.

Synchronous Versus Asynchronous Operations

The object can operate in synchronous mode or in asynchronous mode. When the object is operating synchronously, the read and write routines block the MATLAB command line until the operation has completed or a timeout occurs. When the object is operating asynchronously, the read and write routines return control immediately to the MATLAB command line.

Additionally, you can use callback properties and callback functions to perform tasks as data is being written or read. For example, you can create a callback function that notifies you when the read or write operation has finished.

Configuring and Connecting to the Server

For this example, we will use an echo server that is provided with the toolbox. The echo server allows you to experiment with the basic functionality of the UDP objects without connecting to an actual device. An echo server is a service that returns to the sender's address and port, the same bytes it receives from the sender.

echoudp('on', 8000);

You need to create a UDP object. In this example, create a UDP object associated with the host 127.0.0.1 (your local machine), port 8000. In general, the host name or address and the host port will be defined by the device and your network configuration.

u = udp('127.0.0.1', 8000);

Before you can perform a read or write operation, you must connect the UDP object to the server with the fopen function.

fopen(u)

If the object was successfully connected, its Status property is automatically configured to open.

u.Status
ans = 
    open

Note

UDP ports can be shared by other applications to allow for multiple applications to listen to the UDP datagrams on that port. This allows for the ability to listen to UDP broadcasts on the same local port number in both MATLAB and other applications. You can enable and disable this capability with a new property of the UDP object called EnablePortSharing. See Enable Port Sharing over UDP.

Reading Data Asynchronously

You can read data asynchronously with the UDP object in one of these two ways:

  • Continuously, by setting ReadAsyncMode to continuous. In this mode, data is automatically stored in the input buffer as it becomes available from the server.

  • Manually, by setting ReadAsyncMode to manual. In this mode, you must call the readasync function to store data in the input buffer.

The fscanf, fread, fgetl and fgets functions are used to bring the data from the input buffer into MATLAB. These functions operate synchronously.

Reading Data Asynchronously Using Continuous ReadAsyncMode

To read data continuously:

u.ReadAsyncMode = 'continuous';

To send a string to the echoserver:

fprintf(u, 'Hello net.');

Because the ReadAsyncMode property is set to continuous, the object is continuously asking the server if any data is available. The echoserver sends data as soon as it receives data. The data is then read from the server and is stored in the object's input buffer.

u.BytesAvailable
ans = 
    11

You can bring the data from the object's input buffer into the MATLAB workspace with fscanf.

mystring = fscanf(u)
mystring = 
    Hello net.

Reading Data Asynchronously Using Manual ReadAsyncMode

You can also read data manually.

u.ReadAsyncMode = manual;

Now, send a string to the echoserver.

fprintf(u, 'Hello net.');

Once the last fprintf function completes, the server begins sending data. However, because ReadAsyncMode is set to manual, the object is not reading the data being sent from the server. Therefore no data is being read and placed in the input buffer.

u.BytesAvailable
ans = 
    0

The readasync function can asynchronously read the data from the server. The readasync function returns control to the MATLAB command line immediately.

The readasync function takes two input arguments. The first argument is the server object and the second argument is the size, the amount of data to be read from the server.

The readasync function without a size specified assumes size is given by the difference between the InputBufferSize property value and the BytesAvailable property value. The asynchronous read terminates when:

  • The terminator is read as specified by the Terminator property

  • The specified number of bytes have been read

  • A timeout occurs as specified by the Timeout property

  • The input buffer is filled

An error event will be generated if readasync terminates due to a timeout.

The object starts querying the server for data when the readasync function is called. Because all the data was sent before the readasync function call, no data will be stored in the input buffer and the data is lost.

When the UDP object is in manual mode (the ReadAsyncMode property is configured to manual), data that is sent from the server to the computer is not automatically stored in the input buffer of the UDP object. Data is not stored until readasync or one of the blocking read functions is called.

Manual mode should be used when a stream of data is being sent from your server and you only want to capture portions of the data.

Defining an Asynchronous Read Callback

You can configure a UDP object to notify you when a terminator has been read using the dispcallback function.

u.ReadAsyncMode = 'continuous';
u.BytesAvailableFcn = 'dispcallback';

Note, the default value for the BytesAvailableFcnMode property indicates that the callback function defined by the BytesAvailableFcn property will be executed when the terminator has been read.

u.BytesAvailableFcnMode
ans = 
    terminator

The callback function dispcallback displays event information for the specified event. Using the syntax dispcallback(obj, event), it displays a message containing the type of event, the name of the object that caused the event to occur, and the time the event occurred.

callbackTime = datestr(datenum(event.Data.AbsTime));
fprintf(['A ' event.Type ' event occurred for ' obj.Name ' at ' 
     callbackTime '.\n']);

Using Callbacks During an Asynchronous Read

Once the terminator is read from the server and placed in the input buffer, dispcallback is executed and a message is posted to the MATLAB command window indicating that a BytesAvailable event occurred.

fprintf(u, 'Hello net.')
u.BytesAvailable
ans = 
    11

data = fscanf(u)
data = 
    Hello net.

If you need to stop an asynchronous read or write operation, you do not have to wait for the operation to complete. You can use the stopasync function to stop the asynchronous read or write.

stopasync(u);

The data that has been read from the server remains in the input buffer. You can use one of the synchronous read functions to bring this data into the MATLAB workspace. However, because this data represents the wrong data, the flushinput function is called to remove all data from the input buffer.

flushinput(u);

Writing Data Asynchronously

You can perform an asynchronous write with the fprintf or fwrite functions by passing 'async' as the last input argument.

Configure the object to notify you when an asynchronous write operation completes.

u.OutputEmptyFcn = 'dispcallback';
fprintf(u, 'Hello net.', 'async')

UDP sends and receives data in blocks that are called datagrams. Each time you write or read data with a UDP object, you are writing or reading a datagram. In the example below, a datagram with 11 bytes (10 ASCII bytes plus the LF terminator) will be sent to the echoserver. Then the echoserver will send back a datagram containing the same 11 bytes.

Configure the object to notify you when a datagram has been received.

u.DatagramReceivedFcn = 'dispcallback';
fprintf(u, 'Hello net.', 'async')

Note

If you need to stop an asynchronous read or write operation, you do not have to wait for the operation to complete. You can use the stopasync function to stop the asynchronous read or write.

Cleanup

If you are finished with the UDP object, disconnect it from the server, remove it from memory, and remove it from the workspace. If you are using the echo server, turn it off.

fclose(u);
delete(u);
clear u
echoudp('off');