UDT Tutorial: Transfer Data

Transfer Data

After the UDT connection is built up, transferring data is much easier than using sockets send or recv. In this section we will introduce the blocking and non-blocking methods of data transfer.

Blocking Sending

Blocking is the simplest mode, a UDT send call will be blocked until the buffer is successfully received by the peer side. If multiple send calls are used in multi-thread applications, all calls will be blocked and released one by one as the buffers in the waiting queue are sent out. However, the release order is NOT guaranteed by UDT, but depends on the thread mechanism on specific operating systems.

The default sending mode of UDT is non-blocking for performance purposes (to eliminate the waiting time between two buffers' sending).

Blocking Receiving

Receiving is in blocking mode by default. The situation is similar to block sending. Unlike sockets, UDT recv will not return until it receives exactly the amount of data it is required by the application, except when the connection is broken. Overlapped IO is used in this mode.

Non-Blocking Sending

What a non-blocking sending call does is simply to put the buffer into the sending queue. Note that the semantics is not the same as the sockets non-blocking call. There are two issues that must be considered.

The first is that the application needs to care about the sending queue size. Since it is unknown to the application if the previous buffers have been sent out, a careless application may crash the host by using up the physical memory. A better way is to check the sending buffer size by the getCurrSndBufSize method before a non-blocking send is called.

The following example demonstrates the idea:

while (true)

{

   // Produce data here...

   ...

   while (udt.getCurrSndBufSize() > 100000000) //Using a large value here, but not too large for the system memory

      usleep(10);

   udt.send(data, len)

};

If the application sends out raw data and does not need them any more after they are sent, the UDT_MFLAG can be set to let the allocated memory be released automatically by UDT.

The second problem occurs after data sending. When applications are to exit or close UDT connection, they should use getCurrSndBufSize to check if all the data in the buffer has been sent out.

Non-Blocking Receiving

Non-blocking receiving is much simpler than sending. It checks the size of received data in the UDT buffer. If there is enough data to fulfill the buffer, the recv call returns successfully, otherwise it throws an exception with the buffer untouched.

We do not encourage the use of non-blocking receiving because it has lower performance than blocking receiving, especially when the buffer is large.