#include "ipx_app.h" int t_rcvudata( int ipxFd, struct t_unitdata *ud, int *flags )
ud.udata.buf
field points to the data that was sent
with the IPXThis call is supported as documented in t_rcvudata(3xti).
The t_unitdata structure has the following format:
struct t_unitdata { struct netbuf addr; struct netbuf opt; struct netbuf udata; };The netbuf structure has the following format:
struct netbuf { unsigned int maxlen; unsigned int len; char *buf; };The address (
addr.buf
field) must point to an ipxAddr_t structure, which has the following format:
typedef struct ipxAddress{ unsigned char net[ 4 ]; unsigned char node[ 6 ]; unsigned char sock[ 2 ]; } ipxAddr_t;This call is the reverse of t_sndudata. The address of the sender is returned to the
ud.addr
field. The packet type is in the ud.opt
field, and the packet data is in the ud.udata
field.
The len
field of opt, udata, and addr is set according to the incoming packet. The amount of data received in the IPX packet is in ud.udata.len
.
If a complete data unit is received by the t_rcvudata call, flags will be set to 0. If more data remains to be received flags will be set to T_MORE.
Because IPX is a datagram service, there is no flow control on incoming data. If the IPX application cannot service the incoming data as fast as it is generated, the IPX driver drops the excess incoming packets.
Both static and dynamic allocation are illustrated in the examples below.
/* This examples uses statically allocated data buffers. */struct t_unitdata ud; unsigned char ipxPacketType; unsigned char ipxDataBuf[IPX_MAX_DATA]; ipxAddr_t sourceAddress; int flags = 0;
/* When the t_rcvudata unblocks, ipxPacketType will have the packet type ** from the IPX packet. */
ud.opt.len = sizeof(ipxPacketType); ud.opt.maxlen = sizeof(ipxPacketType); ud.opt.buf = (char *)&ipxPacketType;
/* When the t_rcvudata unblocks, sourceAddress will have the IPX address of ** the datagram sender */
ud.addr.len = sizeof(ipxAddr_t); ud.addr.maxlen = sizeof(ipxAddr_t); ud.addr.buf = (char *)&sourceAddress;
/* When the t_rcvudata unblocks, ipxDataBuf will contain the data in the ** IPX packet */
ud.udata.len = IPX_MAX_DATA; ud.udata.maxlen = IPX_MAX_DATA; ud.udata.buf = (char *)&ipxDataBuf[0]; if (t_rcvudata (ipxFd, &ud, &flags)<0) { t_error( "t_rcvudata failed" ); ... }
/* This examples uses dynamic allocation and checks for receipt of a complete data unit. */struct t_unitdata *ud; int flags = 0;
if ((ud = (struct t_unitdata *) t_alloc (ipxFd, T_UNITDATA, T_ALL)) == NULL) { t_error ( "t_alloc failed"); ... } do { if (t_rcvudata ( ipxFd, ud, &flags) <0 ) { t_error ( "t_rcvudata failed"); ... } ... } while ( flags == T_MORE );