HPlogo NetIPC 3000/XL Programmer's Reference Manual: HP 3000 MPE/iX Computer Systems > Chapter 1 NetIPC Fundamentals

Using NetIPC for Interprocess Communication

» 

Technical documentation

Complete book in PDF
» Feedback

 » Table of Contents

 » Glossary

 » Index

The following paragraphs describe the tasks for using NetIPC for process-to-process communication in programs which are:

  • Establish a connection.

  • Send and receive data over the connection.

  • Shut down the connection.

These discussions are based on access to level 4 (TCP) but most principles apply to direct access to level 3 (X.25). Information specific to X.25 is noted in the discussion.

After establishing a virtual circuit, you can use other NetIPC functions which are described in this chapter under the heading, "Additional NetIPC Functions".

Establishing a Level 4 Connection

The following paragraphs are a call-by-call explanation of the dialogue through which a virtual circuit connection is built. This example uses the socket registry facility by establishing names for call sockets with IPCNAME and retrieving the names with IPCLOOKUP. Figure 1-9 “Using IPCDEST” shows the sequence of calls to use if the address of the socket is known (using IPCDEST).

Only two processes are shown in this example. Either or both of the processes shown can establish virtual circuit connections with other processes. Secondary or auxiliary connections can also be set up between the same two processes.

NOTE: Both of the processes in the following dialogue are assumed to be created and running at their respective nodes. NetIPC does not include a call to schedule remote processes. Refer to the chapter, Remote Process Management, in the Using NS 3000/XL Network Services manual for more information about initializing remote processes with RPM.

1. Creating a Call Socket

Interprocess communication is initiated when Process A and Process B each create a call socket by invoking the NetIPC call IPCCREATE (see Figure 1-2 “IPCCREATE (Processes A and B)”). As explained previously, a call socket is roughly analogous to a telephone with multiple extensions (see Figure 1-1 “Telephone Analogy”). IPCCREATE returns a call socket descriptor to the calling process in its calldesc parameter that describes the call socket, or "telephone extension," that the process has created. This call socket descriptor is then used in subsequent NetIPC calls.

Figure 1-2 IPCCREATE (Processes A and B)

IPCCREATE (Processes A and B)

2. Naming a Call Socket

Process B associates a name with its call socket by calling IPCNAME (see Figure 1-3 “IPCNAME (Process B)”). When a call socket is named, this information is placed in the socket registry at the local node. The name Process B assigns to its call socket must also be known to Process A because Process A must reference it later in its IPCLOOKUP call. (When a socket name is known to both processes in this way, it is called a well-known name.) Although call sockets do not have to be named, a process cannot gain access to the socket of another process if the socket is not named (unless the address of that socket is known, in which case IPCDEST is used). The socket must be named and be recorded in the socket registry at the node of Process B when Process A calls IPCLOOKUP.

Figure 1-3 IPCNAME (Process B)

IPCNAME (Process B)

3. Looking Up a Call Socket Name

Process A must reference the call socket of Process B by its name in the call to IPCLOOKUP to "look up" the name of the call socket in the socket registry at the node where Process B resides. IPCLOOKUP returns a destination descriptor in its destdesc parameter (see Figure 1-4 “IPCLOOKUP (Process A)”). The destination descriptor indicates the location of the destination call socket which is owned by Process B. IPCLOOKUP is similar to a telephone company's directory assistance service: Process A calls the "operator" ( IPCLOOKUP), and gives him/her a "city" ( location parameter) and a "name" (socketname parameter). Using the "city," that is, the node name or environment ID, the operator looks for the name in the proper "telephone directory" (socket registry). Once the name is found, the operator returns a "telephone number" (destdesc parameter) to the caller.

Figure 1-4 IPCLOOKUP (Process A)

IPCLOOKUP (Process A)

4. Requesting a Connection

Process A specifies the destination descriptor returned by IPCLOOKUP and the call socket descriptor returned by IPCCREATE in its call. With these two parameters, IPCCONNECT requests a virtual circuit connection between Process A and Process B (see Figure 1-5 “IPCCONNECT (Process A)”). This could be compared to dialing a phone number. IPCCONNECT then returns a VC socket descriptor in its vcdesc parameter that describes the VC socket endpoint of the connection at Process A.

Figure 1-5 IPCCONNECT (Process A)

IPCCONNECT (Process A)

5. Receiving a Connection Request

Using the call socket descriptor returned by its IPCCREATE call, Process B calls IPCRECVCN to receive any connection requests. In this example, Process B receives a connection request from Process A. (Process A "dialed its telephone" to call Process B when it called IPCCONNECT.) IPCRECVCN returns a VC socket descriptor in its vcdesc parameter (see Figure 1-6 “IPCRECVCN (Process B)”). This VC socket is the endpoint of the virtual circuit at Process B. The connection will not be established, however, until Process A calls IPCRECV. In the telephone analogy, IPCRECVCN is similar to picking up a ringing phone and saying "hello".

Figure 1-6 IPCRECVCN (Process B)

IPCRECVCN (Process B)

6. Checking the Status of a Connection

Process A calls IPCRECV using the VC socket descriptor returned by its IPCCONNECT call. IPCRECV returns the status of the connection (successful/unsuccessful) initiated by IPCCONNECT. If the status is successful, the connection has been established and Process A and Process B can "converse" over the new virtual circuit (see Figure 1-7 “IPCRECV (Process A)”). Compared to the telephone system, IPCRECV is similar to saying "hello" in response to the "hello" from the other end of the phone. IPCRECV can also be used to receive data. This function is described in the IPCRECV call discussion later in this section.

Figure 1-7 IPCRECV (Process A)

IPCRECV (Process A)

Connection Establishment Summary

The following discussions summarize the methods for establishing connections using NetIPC intrinsics.

Connection Establishment Using IPCNAME

<Figure 1-8 “Establishing a Connection (Summary)” illustrates the sequence of NetIPC calls that is used to establish a virtual circuit connection. This figure summarizes the information presented in previous Figures.

Figure 1-8 Establishing a Connection (Summary)

Establishing a Connection (Summary)
Connection Establishment Using IPCDEST

Figure 1-9 “Using IPCDEST” illustrates the sequence of NetIPC calls that is used to establish a virtual circuit connection when the protocol relative address of the remote node is known.

Figure 1-9 Using IPCDEST

Using IPCDEST

Sending and Receiving Data Over a Connection

Once a virtual circuit connection is established, the two processes can exchange data using the NetIPC calls IPCSEND and IPCRECV. Either process can send or receive data. IPCSEND is used to send data on an established connection; it is analogous to "speaking" over a telephone connection. IPCRECV is used to receive data on an established connection; the use of IPCRECV is similar to "listening" at our telephone handset. (Note that IPCRECV has a dual function: to complete a virtual circuit connection as well as to receive data on a previously established connection.)

X.25 Access

Direct access to level 3 (X.25) provides message mode transfer. Stream mode is not supported for X.25. Each IPCRECV returns a complete message (provided the data length specified is of sufficient size). The X.25 protocol signals the end of message and NetIPC buffers the message until an IPCRECV (or required IPCRECVs), retrieve it.

TCP Access

For TCP access, all data transfers between user processes are in stream mode. In stream mode, data is transmitted as a stream of bytes with no end-of-message markers. This means that the amount of data received in an individual IPCRECV is not necessarily equivalent to the amount of data sent in an IPCSEND call. In fact, the data received may contain part of a message or even several messages sent by multiple IPCSEND calls.

You specify the maximum number of bytes you are willing to receive through a parameter of IPCRECV. When the call completes, that parameter contains the number of bytes actually received. This will never be more than the maximum amount you requested, but it may be less. The data you receive will always be in the correct order (in the order that the messages were sent), but there is no indication of where one message ends and the next one starts. It is up to the receiving process to check and interpret the data it actually receives. An application which does not need the information in the form of individual messages can simply process the data on the receiving side.

If an application is concerned about messages, the programmer must devise a scheme that allows the receiving side to determine what the messages are. If the messages are of a known length, the receiving process can execute a loop which calls IPCRECV with a maximum number of bytes equal to the length of the portion of the message not yet received.

Since IPCRECV returns to you the actual number of bytes received, you can continue to execute the loop until all the bytes of the message have been received. The following Pascal program fragment demonstrates this idea:

received_len := 0;
while (received_len < msg_length) and (errorcode = 0) do
  begin
    data_len := msg_length - received_len;   
    ipcrecv( connection, tempbfr, data_len,,,errorcode );
    if errorcode = 0
        then strmove(data_len,tempbfr,1,databfr,
            received_len+1);
    received_len := received_len + data_len;
end; 

In the above example, the Pascal function strmove takes each piece of the message received in tempbfr and concatenates it to the portion of the message already in databfr. Upon exiting the loop, the entire message has been stored in databfr.

If the length of the messages are not known, the sending side could send the length of the message as the first part of each message. In that case, the receiving side must execute two IPCRECV loops for each message: first to receive the length and then to receive the data. An example of this technique is shown at the end of this section.

Shutting Down Sockets and Connections

The NetIPC call IPCSHUTDOWN releases a descriptor and any resources associated with it. IPCSHUTDOWN can be called to release a call socket descriptor, a destination descriptor, or a VC socket descriptor. Because system resources are being used whenever descriptors exist, you should probably release them when they are no longer needed.

The call socket is needed as long as a process is expecting to receive a connection request on that socket. A process which receives a connection request can release the call socket any time after the IPCRECVCN connection request, as long as no other connection requests are expected for that call socket.

Similarly, a process which requests a connection can release its call socket any time after the call to IPCCONNECT, as long as it is not expecting to receive any more connection requests for that socket.

For TCP only, a process does not need to create a call socket (via IPCCREATE) at all; instead, it can use a temporary call socket by calling IPCCONNECT without specifying a call socket descriptor. (A temporary call socket is automatically destroyed when the IPCCONNECT call completes.) A process which requests a connection can also release the destination socket any time after the call to IPCCONNECT.

For example, in the section "Establishing a Connection", Process A no longer needs the destination descriptor after calling IPCCONNECT and can use IPCSHUTDOWN to release the destination descriptor. In addition, if Process A does not expect to request additional connections, it can also call IPCSHUTDOWN a second time to release the call socket.

Process B, as described in "Establishing a Connection", can call IPCSHUTDOWN to release its call socket any time after the call to IPCRECVCN (see "Receiving a Connection Request"). Process B should release its call socket only if it does not want to establish additional connections.

Before a process terminates, it should terminate its virtual circuit connections by releasing its VC sockets with IPCSHUTDOWN. If a process does not release its VC sockets before terminating, the system releases them when the process terminates. Because IPCSHUTDOWN takes effect very quickly, all of the data that is in transit on the connection is lost when the connection is shut down. As a result, if there is a possibility that data is in transit on the connection, the processes that share a connection must cooperate to ensure that no data is lost.

X.25 Access

X.25 direct access to level 3 does not support the graceful release bit. Using IPCSHUTDOWN on a VC socket descriptor causes a clear packet to be sent.

To ensure that no data packets are lost before the clear packet is sent, the D bit option can be set in the last IPCSEND. This assures end-to-end acknowledgment of this message before issuing the IPCSHUTDOWN to clear the virtual circuit.

Another method to ensure no lost packets is to send an unimportant message as the last message. The following example shows the calling sequence you would use. Note that the "dummy" message may or may not be received by the last IPCRECV. If the last message is not received, a SOCKERR 67 "CONNECTION FAILURE DETECTED" is returned.

    IPCSEND       --->      IPCRECV
    (important message)     (important message
                            received)
 
                 <----      IPCSEND
                            (dummy message sent)
    IPCRECV
    (receive dummy          IPCSHUTDOWN
     message) 
 
    IPCSHUTDOWN

TCP Access

To ensure that no data is lost, the IPCSHUTDOWN graceful release bit can be set, and the following sequence of steps can be followed:

  • Process A calls IPCSHUTDOWN and sets bit 17, the graceful release flag. Process B receives a message (with an IPCRECV) informing it that Process A has called for graceful release. (This message is sent to B automatically when A sets the graceful release flag.) Process A enters a simplex-in state; meaning, it can receive, but not send, data. Process B will enter a simplex-out state, that is, it can send but cannot receive data. As a result, data that is in transit to Process A (which initiated the graceful release shutdown) will reach Process A without being lost.

  • Next, one of two steps must occur to completely shut down the connection. Either (1) Process B initiates with or without its own graceful release or (2) Process A calls IPCSHUTDOWN without the graceful release option.

  • This releases Process A's VC socket descriptor and shuts down the connection. In this case, Process B must also release its socket descriptor by calling IPCSHUTDOWN.

    If the graceful release option is not used (this may be necessary, for example, if the remote node does not support graceful release) the following steps should be followed when shutting down a connection.

  • Process A sends a "last message" to Process B via an IPCSEND call. This message contains data that is recognized by Process B as a termination request, and may also contain data to be processed by Process B. Process A then calls IPCRECV.

  • Process B receives the message from Process A with a call to IPCRECV and sends a "confirmation message" to Process A via IPCSEND. This message contains data that indicates to Process A that it is okay to terminate the connection, and may also contain data to be processed by Process A. Process B then calls IPCRECV.

  • Process A receives a "confirmation message" from Process B via the call to IPCRECV and calls IPCSHUTDOWN to release its VC socket descriptor and shut down the connection.

  • The IPCRECV call of Process B completes with a result parameter value of 64 ("REMOTE ABORTED THE CONNECTION"). It then calls IPCSHUTDOWN to release its VC socket.

Additional NetIPC Functions

Once a virtual circuit is established between processes, descriptors can be given away, names can be erased, and other functions can be performed. The following NetIPC calls are provided in addition to those described in the previous paragraphs to enable you to perform these additional functions. A brief introduction to each call and its use follows. A complete description of NetIPC calls is provided in Chapter 3 “NetIPC Intrinsics”

  • IPCCONTROL. Performs special operations on sockets such as enabling synchronous mode, and changing asynchronous timeout values.

  • IPCDEST. Returns a destination descriptor which can be used to send messages to another process. This is an alternative to naming the descriptor with IPCNAME and acquiring it with IPCLOOKUP.

  • IPCGET. The companion call to IPCGIVE. Receives a call socket or virtual connection given away by a process that has called IPCGIVE. This call is similar to IPCLOOKUP because it enables your process to acquire a descriptor that can be used in subsequent NetIPC calls.

  • IPCGIVE. The companion call to IPCGET. Releases ownership of a descriptor to NetIPC so that it can be acquired by another process via a call to IPCGET.

  • IPCNAMERASE. Does the reverse of IPCNAME: it removes a name associated with a call socket from the socket registry. Only the owner of a call socket descriptor can remove its name.

Feedback to webmaster