5.7  Sending and Receiving Connectionless Data

A kernel-mode client can engage in connectionless communication by sending data over the network as soon as it has successfully opened a transport address in the underlying TDI transport.

To receive data in this manner, the client must register its ClientEventReceiveDatagram and, possibly, ClientEventChainedReceiveDatagram handlers with the underlying transport or issue an explicit TDI_RECEIVE_DATAGRAM request to the underlying transport.

For more information about opening a transport address and registering an event handler on that address, see Section 5.1.

Sending a Datagram

Figure 5.9 shows how a TDI client sends a datagram to a remote-node address.

Figure 5.9    Sending a Datagram

As this figure shows, sending a datagram is similar to sending connection-oriented data. However, the local-node client submits a TDI_SEND_DATAGRAM request to its underlying transport on an open transport address, instead of a send request on an established endpoint-to-endpoint connection as already described in Section 5.6.

A TDI_SEND_DATAGRAM IRP requests the underlying transport to transmit a client-supplied datagram to an unknown number of remote-node clients at a particular remote-node transport address.

The local-node client with an open transport address can use TdiBuildSendDatagram to set up such a request. Along with the target remote-node address, the client provides buffered data that can be any size up to the maximum the TDI transport driver allows for datagram sends. The client can determine this limit by querying the underlying transport, as described already in Section 5.4.

Receiving a Datagram

Figure 5.10 shows how a kernel-mode client receives a datagram through its underlying transport from a remote node.

Figure 5.10    Receiving a Datagram

As this figure shows, receiving a datagram is similar to receiving connection-oriented data. However, the local-node client submits a TDI_RECEIVE_DATAGRAM request to its underlying transport on its open transport address, instead of a receive request on an established endpoint-to-endpoint connection as already described in Section 5.6.

However, the client can receive a datagram sent by any remote-node client that specifies the local client's open transport address as the destination of the datagram. Other local clients that have opened the same transport address can also receive the same datagram.

A TDI_RECEIVE_DATAGRAM IRP requests the underlying transport to return a datagram from any remote-node client that has sent one to the local-node client's open transport address. The local-node client can use TdiBuildReceiveDatagram to set up such a request. Along with a pointer to the file object that represents its open transport address, the client provides a buffer that can be any size up to the maximum the TDI transport driver allows for received datagrams. Because TDI transports never fragment datagrams, the local-node client usually issues one receive-datagram request to accept one datagram.

When it satisfies such a request, the transport driver copies a received datagram into the client-supplied buffer and returns the transport address of the remote-node client that sent the datagram with the completed IRP. If the received datagram is too large for the buffer, the transport returns as much data as possible and discards the remaining data.

A client can also receive a datagram from a remote node as an event notification by the underlying TDI transport driver. For these notifications, the transport removes its header from the TSDU that it receives from the remote node and calls the client’s registered ClientEventReceiveDatagram, or possibly ClientEventChainedReceiveDatagram, handler. ClientEventReceiveDatagram can do one of the following:

·Return a not-accepted status immediately, effectively telling the transport that the TSDU is not of interest to the client.

·Copy as much data as possible into an internal buffer and set up a TDI_RECEIVE_DATAGRAM request for the remainder of the TSDU if the transport provided only part of the data and return control.

·Copy all of the TSDU into an internal buffer and return control.

Non-buffering transport drivers can discard data after a receive-datagram event indication if the ClientEventReceiveDatagram does not copy the data or return an IRP. Buffering transport drivers retain a certain amount of datagram information that their clients can retrieve later by making explicit TDI_RECEIVE_DATAGRAM requests.

The ClientEventChainedReceiveDatagram handler is always given read-only access to a full TSDU by the underlying transport. Consequently, this routine has no need to issue a TDI_RECEIVE_DATAGRAM request to the underlying transport or to process partial indications of received TSDUs.

For more information about registering ClientEventXxx handlers, see Section 5.1.