5.3. Basic Features - UnreliableProtocol

Description

UnreliableProtocol is similar to UDP and has the following characteristics.

  • Data is not guaranteed to arrive at the destination.
  • Data may not be received in the order that it was sent.
  • The amount of data that can be sent at one time is limited.

Process Flow

This section describes how to initialize this class, use it to send and receive data, and then finalize it.

Initialization

Start by creating an instance of UnreliableProtocol using the Transport::CreateProtocol() function. Pass the handle you got when instantiating UnreliableProtocol to the Transport::GetProtocol() function to get a pointer to the instance you created. Next, call the UnreliableProtocol::Initialize() function. Because this includes processes for memory allocation, it must be executed between the BeginSetup() and EndSetup() functions.

Code 5-10. Initializing UnreliableProtocol
nn::Result r = nn::pia::transport::BeginSetup();
PIA_ASSERT(r.IsSuccess());

// Initialization of the Transport class.
...
...

nn::pia::transport::Transport* pTransport = nn::pia::transport::Transport::GetInstance();
PIA_ASSERT(PIA_IS_VALID_POINTER(pTransport));

// Create an instance of UnreliableProtocol (communication where data is not guaranteed to arrive).
// You can pass the port number as a parameter to the CreateInstance() function. 0 is used here as the default parameter.
// The handle returned by the CreateProtocol() function is needed later, so keep it for now.
m_hUnreliable = pTransport->CreateProtocol<nn::pia::transport::UnreliableProtocol>();


// Use this handle to get a pointer to the instance, and call the Initialize() function.
// You can specify the number of buffers for receiving data in the Initialize() function. Specify a value large enough
// to handle any communication that will take place in the application.
nn::pia::transport::UnreliableProtocol* pUnreliable = NULL;
pUnreliable = nn::pia::transport::Transport::GetInstance()->GetProtocol<nn::pia::transport::UnreliableProtocol>(m_hUnreliable);
PIA_ASSERT(PIA_IS_VALID_POINTER(pUnreliable));
const size_t RECV_BUF_NUM = 32;
r = pUnreliable->Initialize(RECV_BUF_NUM);
PIA_ASSERT(r.IsSuccess());
 
// Initialization of other classes.
...
...

r = nn::pia::transport::EndSetup();
PIA_ASSERT(r.IsSuccess());

Sending

Call the UnreliableProtocol::Send() function to send data to a single station.

UnreliableProtocol does not guarantee that data that is sent will arrive at the intended destination. Even if the Send() function returns a result indicating that the send operation was successful, that data may not arrive at the destination station.

Use the UnreliableProtocol::SendToAll() function to send the same data to all of the stations in a session. This bundles the internal send processes and reduces CPU load in comparison with calling the Send() function multiple times to send data to each station. This allows you to efficiently send data to multiple stations at one time—particularly when using local communication networks on the CTR because data can be sent and received using the broadcast feature in the UDS library.

Code 5-11. Sending Data Using UnreliableProtocol
// Get a pointer to the protocol instance.
nn::pia::transport::UnreliableProtocol* pUnreliable = NULL;
pReliable = nn::pia::transport::Transport::GetInstance()->GetProtocol<nn::pia::transport::UnreliableProtocol>(m_hUnreliable);
PIA_ASSERT(PIA_IS_VALID_POINTER(pUnreliable));


 
// Send execution and error handling.
nn::Result r = pUnreliable->Send(destStationId, data, dataSize);
if(r.IsSuccess())
{
    // OK. Do nothing.
}
else if(r==nn::pia::transport::ResultIsNotInCommunication())
{
    // ResultIsNotInCommunication indicates that the station was not ready for communication. This sample ignores this result value.
}
else
{
    PIA_TRACE_RESULT(r);
    PIA_ASSERTMSG(false, "Programming error.");
}

Receiving

Call the UnreliableProtocol::Receive() function to receive data.

PiaTransport uses the polling method to receive data. UnreliableProtocol::Receive() returns ResultNoData as soon as there is no more data to be received. At that time, terminate the receive process.

Code 5-12. Receiving Data Using UnreliableProtocol
nn::Result r;

// Get a pointer to the protocol instance.
nn::pia::transport::UnreliableProtocol* pUnreliable = NULL;
pUnreliable = nn::pia::transport::Transport::GetInstance()->GetProtocol<nn::pia::transport::UnreliableProtocol>(m_hUnreliable);
PIA_ASSERT(PIA_IS_VALID_POINTER(pUnreliable));

// The variables for storing receive data.
nn::pia::StationId srcId;
bit8 buf[nn::pia::transport::UnreliableProtocol::MAX_DATA_SIZE]; // Allocate an array of the maximum size of data that could arrive.
size_t receivedSize;

// Receiving data and error handling.
r = pUnreliable->Receive(&srcId, buf, &receivedSize, sizeof(buf));
if(r.IsSuccess())
{
    // The case where data was received successfully.
    PIA_CACHED_PRINTF("Received %d bytes from Station %d.\n", receivedSize, srcId);
}
else if(r==nn::pia::ResultNoData())
{
    // The case where data has not yet arrived. In this event, do nothing.
}
else
{
    PIA_TRACE_RESULT(r);
    PIA_ASSERTMSG(false, "Programming error.");
}

Finalization

To finalize UnreliableProtocol, call the UnreliableProtocol::Finalize() function and then call the Transport::DestroyProtocol() function to destroy the instance of UnreliableProtocol.

Code 5-13. Finalizing UnreliableProtocol
nn::pia::transport::UnreliableProtocol* pUnreliable = pTransport->GetProtocol<nn::pia::transport::UnreliableProtocol>(m_hUnreliable);
if(PIA_IS_VALID_POINTER(pUnreliable))
{
    pUnreliable->Finalize();
    pTransport->DestroyProtocol(m_hUnreliable);
    m_hUnreliable = 0; // Clear the handle.
}

Amount of Data That Can Be Sent at One Time

With UnreliableProtocol, the amount of data that can be sent at one time with the Send() or SendToAll() function is limited to the size of the packet payload. The UnreliableProtocol::MAX_DATA_SIZE constant defines the maximum amount of data that can be sent at one time. However, the actual packet payload size can change depending on whether the packet is signed and which MTU settings are used for Internet communication.

Use the UnreliableProtocol::GetDataSizeLimit() function to get the limit on the data size that can be sent with the UnreliableProtocol send functions. The value returned by this function accounts for packet signatures and the MTU settings present on the network. The value returned by the GetDataSizeLimit() function never exceeds MAX_DATA_SIZE.

When you attempt to send data that exceeds the size returned by the GetDataSizeLimit() function when calling an UnreliableProtocol send function, a ResultInvalidArgument error is returned.