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:
Function | Purpose |
---|---|
fprintf | Write text to a server. |
readasync | Asynchronously read bytes from a server. |
stopasync | Stop an asynchronous read or write operation. |
These properties are associated with reading and writing text asynchronously:
Property | Purpose |
---|---|
BytesAvailable | Indicates the number of bytes available in the input buffer. |
TransferStatus | Indicates what type of asynchronous operation is in progress. |
ReadAsyncMode | Indicates 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
tocontinuous
. In this mode, data is automatically stored in the input buffer as it becomes available from the server.Manually, by setting
ReadAsyncMode
tomanual
. In this mode, you must call thereadasync
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
propertyThe specified number of bytes have been read
A timeout occurs as specified by the
Timeout
propertyThe 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');