Net8 Administrator's Guide
Release 8.1.6

Part Number A76933-01

Library

Product

Contents

Index

Go to previous page Go to next page

10
Enabling Net8 Enhancements for Programmers

Net8 includes an application program interface (API) called Net8 OPEN, that allows programmers to develop both database and non-database applications. In addition, Net8 contains several benefits for programmers, including UNIX client programming, signal handler and alarm programming, Bequeath protocol support, and child process termination. This chapter contains the following sections:

Net8 OPEN

Net8 includes an application program interface (API), called Net8 OPEN, which enables programmers to:

Net8 OPEN provides applications a single common interface to all industry standard network protocols.

The relationship of Net8 OPEN to other products is shown in Figure 10-1.

Figure 10-1 Net8 OPEN


Using Net8 OPEN, you can solve a number of problems, such as:

Net8 OPEN API Function Calls

In contrast to a remote procedure call interface, Net8 OPEN provides a byte stream-oriented API that can be used to develop basic applications which send and receive data. Applications developed with Net8 OPEN must ensure that values sent across the network are interpreted correctly at the receiving end.

The Net8 OPEN API consists of five function calls:

TNSOPEN   

Description: 

Initializes the Net8 OPEN API per-connection handle. This function must be the first Net8 OPEN call that a user makes. Note that tnsopen() does not establish a connection; connections are established by the send and receive calls as needed. 

Synopsis: 

int tnsopen(handlep, name)
void **handlep;
const char *name;

If you are writing a client program that will initiate the connection, "name" contains a net service name in the same format as those in a tnsnames.ora file.

If you are writing a server program, "name" should be NULL. Your server program will pick up the connection automatically when you make the first tnsrecv() call to receive data. 

Parameters: 

handlep (IN/OUT): Address to receive Net8 connection handle

name (IN): Net service name 

Prerequisites: 

The handlep parameter must not be NULL 

Returns: 

Upon successful completion a zero value is returned. Otherwise, a positive Net8 API error is returned. 

TNSCLOSE   

Description: 

Shuts down the connection. The user must call this function to close the connection and release the handle properly. 

Synopsis: 

int tnsclose(handlep)
void **handlep;
 

Parameters: 

handlep(IN/OUT): Address of a pointer to a Net8 connection handle 

Prerequisites: 

The handlep parameter must not be NULL. 

Returns: 

Upon successful completion a zero value is returned, and *handlep is set to NULL. Otherwise, a positive Net8 API error number is returned. 

TNSSEND   

Description: 

Sends data to the Net8 connection handle

In the first call to tnssend() on the client side, the connection is established before any data is sent to the handle. The client application must first call tnssend() after tnsopen() to establish a connection to the server. It is an error if the client application calls tnsrecv() first, or if the server program calls tnssend() first.

Note that this also means that the tnssend() call may return errors related to connection establishment. For example, if you have given the incorrect TNS address, the first error occurs on tnssend() call rather than on the tnsopen()

Synopsis: 

int tnssend(handle, data, length)
void *handle;
const void *data;
size_t *length;
 

Parameters: 

handle(IN/OUT) - Pointer to Net8 connection handle returned by tnsopen()

data(IN): Pointer to data to be sent

length(IN/OUT): Pointer to the length of data to be sent in bytes and the actual number of bytes written on return 

Prerequisites: 

The parameters must not be NULL. 

Returns: 

Upon successful completion a zero value is returned, and the actual number of bytes written is returned as the value pointed to by the length parameter. Otherwise, a positive Net8 API error number is returned. 

TNSRECV   

Description: 

Receives data from the Net8 connection handle

In the first call to tnsrecv() on the server side, the connection is established before data is received from the handle. The server must first call tnsrecv() after tnsopen() to accept the connection from the client.

Incoming connections are accepted by the Net8 Listener (tnslsnr), which automatically spawns off a copy of your server program when needed, and hands it the new connection. You must configure the network listener with the location of your server program for this to occurs. 

Synopsis: 

int tnsrecv(handle, data, length)
void *handle;
void *data;
size_t *length;
 

Parameters: 

handle(IN/OUT): Pointer to Net8 connection handle returned by tnsopen()

data(IN/OUT): pointer to buffer to receive data

length(IN/OUT): Pointer to the length of buffer to receive data and actual number of bytes received on return 

Prerequisites: 

All parameters must not be NULL. 

Returns: 

Upon successful completion a zero value is returned, and the actual number of bytes received is returned as the value pointed to by the length parameter. Otherwise, a positive Net8 API error number is returned. 

TNSCONTROL   

Description: 

Sets the connection to blocking or nonblocking mode 

Synopsis: 

int tnscontrol(handle, cmd)
void *handle;
int *cmd;
 

Parameters: 

handle(IN): Pointer to Net8 connection handle returned by tnsopen()

cmd(IN): Option to apply to the connection. Currently supported values are:

  • TNSAPINONBLOCKING

    Sets connection into nonblocking mode

  • TNSAPIBLOCKING

    Sets connection into blocking mode

 

Prerequisites: 

The handle must not be NULL, and cmd must be one of the supported commands. 

Returns: 

A zero value is returned if the option is successfully set. 

Finding the Net8 OPEN Applications Program Interface

The applications program interface is provided as part of the standard Net8 installation. To use it, you need the following:

Building Your Own Application

Modules which make reference to Net8 OPEN functions should include TNSAPI.H, as follows:

#include <tnsapi.h>

Your makefile (or other location for your build command) should ensure that the include path is set properly so that it can find TNSAPI.H. Refer to the sample makefiles provided in your installation.

Configuring the System to Use Your Net8 OPEN Application

To configure Net8 to recognize your Net8 OPEN application:

  1. Add the location of your server program to the listener.ora file, so that the listener knows to start your server if a connection request is received.


    Note:

    This is not necessary for release 8.1 configurations, as database instance registration registers service information with the listener. 


    To do this, choose a system identifier (SID) name for your service similar to that of an Oracle database. Do not pick the same SID as your database.

    For example, if you are configuring a "chat" program, you could call the SID "chatsid". Place the program into the same place as the Oracle server executable, which is normally $ORACLE_HOME/bin on UNIX and ORACLE_HOME\bin on Windows NT.

    You would place the following entry in a listener configuration file as follows:

    sid_list_listener = 
    
          (sid_list =
    
    
        (sid_desc =
    
    (sid_name = chatsid)/*your SID name*/
    (oracle_home = /usr/oracle)/*$ORACLE_HOME bin directory*/
    (program = chatsvr)/*the name of your server program*/)
    
    

    You need to restart the listener, so it will recognize the new service.

  2. Add the address of your application server to the tnsnames.ora file.

    For example, if your listener is listening on the following address:

    (description=(address=(protocol=tcp)(host=unixhost)(port=1521)))
    
    

    and, you want people to refer to the service you created above as chat, add the following to the tnsnames.ora file:

    chat=
    (description=
    
    (address=(protocol=tcp)(host=unixhost)(port=1521))
    (connect_data=(service_name=chat)))
    
    
  3. Place the executable for your service in the same directory as your Oracle server executable. On UNIX platforms, place the executable in the $ORACLE_HOME/bin directory indicated in your listener.ora file. In this example, you would place the program "chatsvr" in the location /usr/oracle/bin/chatsvr.

    If needed on your operating system, you also must ensure that you have permission to execute your program.

    Sample Programs

    Two sample applications are provided with Net8 OPEN:

    • finger

      This is a utility that connects to the server that retrieves information about who is logged in. This utility includes a pair of programs which demonstrate the basic steps involved in building a distributed application. The client program runs on both Solaris and Windows NT; the server is UNIX specific.

    • tftp

      This sample client and server program is implemented in UNIX to help you with simple file transfers using the tftp protocol.

    Net8 OPEN API Errors

    This section lists the error numbers that can be returned if one of the above function calls fails. Note that in some cases, connection-related errors may come back from a send or receive call, if the connection has not yet been established at that time.

    20002 - SDFAIL_TNSAPIE - The underlying "send" command failed in tnssend().
    20003 - RECVFAIL_TNSAPIE - The underlying "receive" command failed in tnsrecv().
    20004 - INVSVROP_TNSAPIE - Operation is invalid as the server.
    20005 - INVCLIOP_TNSAPIE - Operation is invalid as the client.
    20006 - HDLUNINI_TNSAPIE - The connection should be initialized by calling 
    tnsopen().
    20007 - INHFAIL_TNSAPIE - Server failed in inheriting the connection from the 
    listener.
    20008 - ACPTFAIL_TNSAPIE - Server failed in accepting the connection request 
    from the client.
    20009 - NULHDL_TNSAPIE - A null handle was passed into the call, which is not 
    allowed.
    20010 - INVOP_TNSAPIE - An invalid operation called was passed into the call.
    20011 - MALFAIL_TNSAPIE - A malloc failed in TNS API call.
    20012 - NLINIFAIL_TNSAPIE - Failed in NL initialization.
    20013 - NMTOOLONG_TNSAPIE - Service name is too long.
    20014 - CONFAIL_TNSAPIE - Client connect request failed.
    20015 - LSNFAIL_TNSAPIE - Server failed to listen for connect request.
    20016 - ANSFAIL_TNSAPIE - Server failed to answer connect request.
    20017 - NMRESFAIL_TNSAPIE - Failed to resolve service name.
    20018 - WOULDBLOCK_TNSAPIE - Operation would block.
    20019 - CTLFAIL_TNSAPIE - Control call failed.
    20020 - TNSAPIE_ERROR - TNS error occurred.
    20021 - INVCTL_TNSAPIE - Invalid operation request in control call.
    

    UNIX Client Programming

    Event programming in UNIX requires the use of a UNIX signal. When an event occurs, a signal flags a process. The process executes code that is relevant to the particular signal generated. UNIX does not allow a single process to set more than one signal handler or alarm for a particular signal call. If a process sets a second signal handler or alarm request on a signal like SIGCHLD (signal on a child process' status change), UNIX nullifies and loses the previous request for the SIGCHLD.

    If any part of your application issues one of these requests, signal handling or alarms may cause the system to lose and never respond to that particular request. Depending on the signal requested, the system may not clean up defunct processes properly because of a signal handler problem.

    Net8 provides two solutions to allow for the use of signal handling and alarms in tandem with Oracle's usage of those requests:

    Signal Handler and Alarm Programming

    Net8 provides an Operating System Dependent (OSD) call that keeps a table of all signal handler or alarm requests for each signal. Any program that uses the signal handler or alarm is now required to use the Oracle OSD calls. This provides a solution for programmers in UNIX who are not allowed to set more than one signal handler or alarm for a particular call. Any program that uses the signal handler or alarm must use the Oracle OSD calls. This is however, currently available only for internal use.

    Until then, if you set all of the client's signal handlers before making any database connections, the OSD call will remember the last signal handler set for the signal and will add it to the signal handler table. Note that by doing this, you cannot disable the signal handler.

    Oracle OSD Signal Handling Rules

    To use the table-driven shared OSD signal handler for all SIGCHLD calls, you must observe the following rules:

    • Know your child process IDs so you can clean up the correct process.

    • Use the waitpid() call instead of wait() on the correct child process ID.

    • Set the waitpid() call to be non-blocking.

    Bequeath

    This section is for UNIX application programmers who use both the UNIX signal handler for tracking child process status changes with the SIGCHLD call and Net8 for the networking portion of their application.

    When a client application is directed to communicate with an Oracle database on the same machine, it uses the Bequeath protocol to establish the connection. The Bequeath protocol enables the client to retrieve information from the database without using the listener. The Bequeath protocol internally spawns a server process for each client application. In a sense, it performs locally the same operation that a remote listener does for your connection.

    Child Process Termination

    Since the client application spawns a server process internally through the Bequeath protocol as a child process, the client application becomes responsible for cleaning up the child process when it completes. When the server process completes its connection responsibilities, it becomes a defunct process. Signal handlers are responsible for cleaning up these defunct processes. Alternatively, you may configure your client sqlnet.ora file to pass this process to the UNIX init process by disabling signal handlers.

    Configure the BEQUEATH_DETACH parameter in the sqlnet.ora file:

    bequeath_detach=yes
    
    

    This parameter causes all child processes to be passed over to the UNIX init process (pid = 1). The init process automatically checks for "defunct" child processes and terminates them.

    Bequeath automatically chooses to use a signal handler in tracking child process status changes. If your application does not use any signal handling, then this default does not affect you.


Go to previous page Go to next page
Oracle
Copyright © 1996-2000, Oracle Corporation.

All Rights Reserved.

Library

Product

Contents

Index