HPlogo X25/9000: X.25/9000 Programmer's Guide > Chapter 3  Establishing and Terminating a Socket Connection

Terminating a Connection

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

When data communications activity over an SVC is completed, the connection should be terminated to free network memory and other resources. This also reduces communications costs because most PDNs charge for transmission and connection time.

An SVC is terminated when a CLEAR REQUEST packet is transmitted. A CLEAR packet can be transmitted to both ends of an SVC by the network provider, or it can be transmitted by one of the processes using the SVC. An X.25 application can transmit a CLEAR REQUEST packet by issuing a close() call on the last open socket descriptor for the socket associated with that SVC, or by issuing a shutdown() call on the socket associated with that SVC.

When a process terminates, all open socket descriptors are closed automatically.

Closing a Socket Descriptor

The close() system call closes a socket descriptor. If a close() is issued on the last open socket descriptor for an SVC socket, a CLEAR REQUEST packet is transmitted on the SVC.

If a process is no longer using a socket descriptor, it should be closed using the close() system call. This technique prevents the SVC from remaining connected after the last process has completed using it.

One of the design strategies described earlier suggested that a server process monitor a listen socket and then fork a child process to handle SVCs as they arrive. The server should close the socket descriptor for the newly-created socket immediately after spawning the child process. This allows the child process to close its socket descriptor and transmit a CLEAR REQUEST packet when needed. If the server did not close its socket descriptor, no CLEAR packet would be transmitted and the SVC would remain connected.

Syntax for close()

The following is the syntax for the close() system call and its parameters:

int err;
int sd;
err = close(sd);
sd

A socket descriptor for a listen socket or an SVC socket. If there are other open socket descriptors for the socket, the socket is no longer usable by the process issuing the call. If there are no other open socket descriptors for the socket, the socket is destroyed and may not be used again by any process. If sd is the last open socket descriptor and a descriptor for an SVC socket, a CLEAR REQUEST packet is transmitted on the SVC.

err

Upon successful completion, err is set to 0. Otherwise, a value of -1 is returned, and errno is set to indicate the error. Even when a nonzero value is returned, sd will not be usable.

The state of the socket and the state of the circuit are independent of one another. When a socket is closed, it vanishes and cannot be accessed again. When a circuit is cleared and the socket is not closed, it can no longer transmit data. However, you can read any unread out-of-band data that arrived on the inbound recv() queues before the clear. Any unread normal data cannot be read. See Chapter 5 “ Receiving and Transmitting Out-of-Band Information” for more on receiving out-of-band data.

When the last close call is executed on a socket descriptor, any data that has not yet been sent or received is lost.

The best way to end a session without losing data is summarized below:

  1. With the send() call, the sending side sends an "I am finished" message—the message content is defined by the application designer.

  2. The receiving side reads this "I am finished" message with the recv() call.

  3. The receiving side closes the virtual circuit with a close() call.

  4. The sending side receives notification of the close() with a recv(OOB) call.

  5. The sending side frees its socket resources by issuing a close() call.

You can specify data and facilities information in the CLEAR packet sent by the final close(). See “Clearing a Switched Virtual Circuit” for details.

For syntax and details on close(), refer to the close(2) entry in your man pages.

NOTE: Closing a socket immediately after sending data can result in data loss.

Shutting Down a Socket

When your program finishes reading or writing on a particular socket connection, it can call shutdown(2) to bring down a part of the connection. Unlike close(), shutdown() affects the entire socket and all other socket descriptors. shutdown() causes all or part of an SVC to be disabled regardless of how many other socket descriptors are open on the socket.

Syntax for shutdown()

The following section describes the syntax for shutdown() and its parameters:

int err;
int sd, how;
err = shutdown(sd, how);
sd

A socket descriptor for a listen socket or an SVC socket. The call affects the entire socket whether or not other socket descriptors are open on the socket.

how

Describes the type of shutdown. Can be set to one of three possible values:

  • 0—disables data reception on the socket, but the connection is not cleared. If data is received on the connection, it is lost. The socket descriptor may still be used to read any unread data and transmit data.

  • 1—clears the connection, any unread data cannot be read using the socket descriptor.

  • 2—disables reception and transmission. A CLEAR REQUEST packet is sent on the SVC. Any unread data can be read.

On a listen socket all how values have the same effect—all requests in the listen queue are cleared an d any requests received after the shutdown() are cleared.

err

Upon successful completion, err is set to 0. Otherwise, a value of -1 is returned, and errno is set to indicate the error.

The shutdown() and close() procedures differ in that shutdown() takes effect regardless of the number of open socket descriptors, while close() takes effect only when the last process with an open socket descriptor makes the call.

NOTE: The shutdown() call does not free internal system resources associated with the socket. To free this buffer space, you must issue a close() call.

Refer to the shutdown(2) entry in your man pages for more information.