Programming with the X/Open Transport Interface (XTI)

Data transfer

Once a user has bound an address to the transport endpoint, datagrams may be sent or received over that endpoint. Each outgoing message is accompanied by the address of the destination user. In addition, the Transport Interface enables a user to specify protocol options that should be associated with the transfer of the data unit (for example, transit delay). As discussed earlier, each transport provider defines the set of options, if any, that may accompany a datagram. When the datagram is passed to the destination user, the associated protocol options may be returned as well.

The following sequence of calls illustrates the data transfer phase of the connectionless-mode server:

   	if ((ud = (struct t_unitdata *)t_alloc(fd,
   	  T_UNITDATA, T_ALL)) == NULL) {
   		t_error("t_alloc of t_unitdata structure failed");

if ((uderr = (struct t_uderr *)t_alloc(fd, T_UDERROR, T_ALL)) == NULL) { t_error("t_alloc of t_uderr structure failed"); exit(6); }

while (1) { if (t_rcvudata(fd, ud, &flags) < 0) { if (t_errno == TLOOK) { /* * Error on previously sent datagram */ if (t_rcvuderr(fd, uderr) < 0) { exit(7); }

fprintf(stderr, "bad datagram, error = %d\n", uderr->error); continue; } t_error("t_rcvudata failed"); exit(8); } /* * query() processes the request and places the * response in ud->udata.buf, setting ud->udata.len */ query(ud);

if (t_sndudata(fd, ud, 0) < 0) { t_error("t_sndudata failed"); exit(9); } } }

query(ud) struct t_unitdata *ud; { /* Merely a stub for simplicity */


The server must first allocate a t_unitdata structure for storing datagrams, which has the following format:
   struct t_unitdata {
   	struct netbuf addr;
   	struct netbuf opt;
   	struct netbuf udata;
addr holds the source address of incoming datagrams and the destination address of outgoing datagrams, opt identifies any protocol options associated with the transfer of the datagram, and udata holds the data itself. The addr, opt, and udata members must all be allocated with buffers large enough to hold any possible incoming values. As described in the previous section, the T_ALL argument to t_alloc will ensure this and will set the maxlen member of each netbuf structure accordingly. Because the provider does not support protocol options in this example, no options buffer will be allocated, and maxlen will be set to zero in the netbuf structure for options. The server also allocates a t_uderr structure for processing any datagram errors, as discussed later in this section.

The transaction server loops forever, receiving queries, processing the queries, and responding to the clients. It first calls t_rcvudata to receive the next query. t_rcvudata will retrieve the next available incoming datagram. If none is currently available, t_rcvudata will block, waiting for a datagram to arrive. The second argument of t_rcvudata identifies the t_unitdata structure in which the datagram should be stored.

The third argument, flags , must point to an integer variable and may be set to T_MORE on return from t_rcvudata to specify that the user's udata buffer was not large enough to store the full datagram. In this case, subsequent calls to t_rcvudata will retrieve the remainder of the datagram. Because t_alloc allocates a udata buffer large enough to store the maximum datagram size, the transaction server does not have to check the value of flags.

If a datagram is received successfully, the transaction server calls the query routine to process the request. This routine will store the response in the structure pointed to by ud, and will set ud->udata.len to specify the number of bytes in the response. The source address returned by t_rcvudata in ud->addr will be used as the destination address by t_sndudata.

When the response is ready, t_sndudata is called to return the response to the client. The Transport Interface prevents a user from flooding the transport provider with datagrams using the same flow control mechanism described for the connection-mode service. In such cases, t_sndudata will block until the flow control is relieved, and will then resume its operation.

© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005