Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Networking /
Chapter 7 - Datagram Delivery Protocol (DDP) / Using DDP


Sending and Receiving Data: An Overview

To send data, you must address each packet to the socket for which it is intended because you cannot open and maintain a connection between two sockets using DDP. To receive a data packet using DDP, you must provide a socket listener process that DDP associates with the socket that your application uses. When you open the socket for your application to use, you must provide a pointer to the socket listener. DDP associates the address of the socket listener with your application's socket so that the .MPP driver can call your socket listener when it receives a packet that is addressed to your socket-client application. DDP maintains a separate entry in its socket table for each socket and socket listener pair.

Applications developers commonly write a single socket-client application that both sends and receives data and that includes a socket listener process to receive data.
To clarify the steps involved in sending and receiving data, this section gives you an overview of these tasks as separate sequences after it explains how to open a socket.
The steps for sending and receiving data refer to sections that are provided later in
this chapter that describe how to

If you want to provide features in addition to the DDP checksum feature to check data and correct errors, you can include them in your application, you can define your own AppleTalk protocol, or you can use a higher-level AppleTalk protocol such as ATP or ADSP instead of calling DDP directly. (For information about DDP checksums, see "Using Checksums" beginning on page 7-19.)

To make your application available to other users of AppleTalk, you must use the NBP PRegisterName function to register the name that represents your socket-client applica-
tion. When you are finished using the socket, you must use the NBP PRemoveName function to remove this name from the NBP names table. See the chapter "Name-Binding Protocol (NBP)" in this book for more information about these functions.

Opening a Socket

To send and receive data using DDP, your application must first open a socket. Opening a socket makes your application a client of that socket. You open a socket with the POpenSkt function. When you open a socket, you must provide a pointer to your socket listener and you must specify 0 for the socket number if you want DDP to dynamically assign a socket.

The POpenSkt function assigns a socket number to your application and enters the number in the socket table along with the pointer to the socket listener that you provide. The POpenSkt function returns the socket number to you in the socket field of the parameter block.

Associating a single socket listener with more than one socket
If your application includes processes that each have their own sockets, you can assign a single socket listener to more than one socket, but each socket should have its own buffer or set of buffers for receiving data.
If you do not want DDP to randomly assign a socket number to your application, you can specify the number of a particular socket for DDP to open. For information on the range of socket numbers from which you can select, see "Assigning Socket Numbers" on page 7-6.

IMPORTANT
You cannot specify a NIL pointer to the socket listener. If you do,
the system on which your application is running will crash.
When your application is finished using a socket, you must use the PCloseSkt function to close the socket.

Sending Data

To send data, you must create a write-data structure that contains the data in a specific format and then call a DDP function to send the data. After you have opened a socket using the POpenSkt function, here are the steps that you follow to send data using DDP:

  1. Create a write-data structure.
  2. Use the DDP function PWriteDDP to send the data.

See "Creating a DDP Write-Data Structure" beginning on page 7-12 for information about how to create a write-data structure using the DDP procedure BuildDDPwds
or your own code.

Packets with long headers can include a checksum that can be used to verify the integrity of the packet data. For information on how to direct DDP to calculate a checksum for data that you want to send, see "Using Checksums" beginning on page 7-19. For details of the contents of a long header, see "The DDP Packet and
Frame Headers" beginning on page 7-14.

Receiving Data

To receive data using DDP, you must provide a socket listener that is part of your socket-
client application. The socket listener code must

There are many ways to design and write a socket-client application and socket listener. This chapter offers one possibility. For details of this sample socket listener and for its code, see "A Sample Socket Listener" beginning on page 7-20.

Note
Your socket-client application should test to find out when the socket listener finishes processing a packet so that the socket-client application can begin its own packet reading and processing.
To receive data, your application must have already opened a socket using the POpenSkt function and have passed the POpenSkt function a pointer to your
socket listener.

Here are the tasks involved in receiving data using DDP:

  1. The .MPP driver calls your socket listener when it receives a packet addressed to your socket-client application. The .MPP driver passes values to you in the CPU's registers. You need to know how the .MPP driver uses these registers and how you can use them. For information about these registers, see "How the .MPP Driver Calls Your Socket Listener" beginning on page 7-13. One of the values that the .MPP driver passes to you is a pointer to the buffer that holds the DDP packet header. You need
    to know how the DDP packet header and the frame header are structured. For information about these headers, see "The DDP Packet and Frame Headers" beginning on page 7-14.
  2. To hold the data that it reads, your socket listener must allocate memory for buffers. In addition to allocating data buffers, either your socket-client application or the socket listener (if you write the socket listener code to carry out this function) must perform some initialization tasks. For information about these tasks and how the sample socket listener handles them, see "Socket Listener Queues and Buffers" beginning on page 7-20, "Setting Up the Socket Listener" beginning on page 7-22,
    and "Initializing the Socket Listener" beginning on page 7-24.
  3. When the .MPP driver calls your socket listener, the socket listener must read the incoming packet into one or more data buffers. To do this, the socket listener uses two processes, ReadPacket and ReadRest, which are implemented as a single routine
    in the hardware driver. The .MPP driver passes you the address of this routine in one of the CPU's registers. For more information, see "Reading an Incoming Packet" beginning on page 7-17.
  4. If you have defined more than one DDP protocol type that your application handles, check the DDP protocol type field of the datagram header (see Figure 7-6 on page 7-15) to determine the protocol type of the packet you have just received.

    The AppleTalk internet address (network number, node ID, and socket number) is insufficient to distinguish between packets intended for different processes that are using the same socket. Your socket listener must use some other information (such as the DDP protocol type or a higher-level protocol header imbedded in the DDP packet data) to make this distinction.

  5. If the packet contains a long header, the socket listener needs to find out if the header contains a checksum. If it does, the socket listener needs to calculate the checksum to determine if the packet's data has been corrupted. For more information, see "Using Checksums" beginning on page 7-19.
  6. The socket listener can now process the packet or pass it to the client application for processing. The sample socket listener provided here writes the packet buffer to a queue that it uses for successfully processed packets and removes the packet from the queue for incoming packets. For a description of how the sample socket listener does this, see "Processing a Packet" beginning on page 7-25.
  7. The client application can now read in the packet for its own purposes. The client application should include code that periodically checks to determine whether the socket listener has finished processing an incoming packet. For a description of how the sample socket listener's client application performs this task and some sample code, see "Testing for Available Packets" beginning on page 7-31.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996