X.25 and XOT Programming using the Sockets API

Switched Virtual Circuits

Writing a program to handle an X.25 SVC (Switched Virtual Circuit) or PVC (Permanent Virtual Circuit) using Sockets is very similar to writing one to use TCP/IP. For the most part, the exact same operations are used, but with some different parameters.

Typical Server

A typical server starts off by creating a listening socket, binding to an address, and then listening for incoming connections. Then the individual connections are accepted, automatically creating a new socket on which that connection is handled. A sockets-based X.25 or XOT server is exactly the same - the main differences to TCP/IP are:

  • the parameters to the socket() call when creating the socket - such as AF_X25 instead of AF_INET for the address family
  • the format of the sockaddr structure in which the address is specified in the call to bind()
  • data transfer (see below)
  • connection closure (see below)

Typical Client

A typical client creates a socket for the connection, and then is ready to connect. A sockets-based X.25 or XOT client is the same - the mains differences with TCP/IP are:

  • the parameters to the socket() call when creating the socket - such as AF_X25 instead of AF_INET for the address family
  • the format of the sockaddr structure in which the address is specified in the call to connect()
  • call parameters - Facilities and Call User Data, for which there is no TCP/IP equivalent
  • data transfer (see below)
  • connection closure (see below)

In addition, if wanting the specify a local (i.e. Calling) address, it needs to use an ioctl() or sockets option to set the address - although this can also be done by using bind(), it is recommended that sockets should not be bound before connect() is used.

Data Transfer

X.25 or XOT Data Transfer is the same as for TCP/IP, except that TCP data is a simple character stream, whereas X.25 packet boundaries are maintained.

Thus when transferring 2 blocks of 2000 bytes each, an X.25 receiver will get two blocks of 2000 bytes each, whereas a TCP receiver might find the data split up or concatenated together.

It is possible with X.25 to transfer a block of zero bytes, which would be impossible with TCP (although it is possible to transmit empty TCP packets - these are used for keep-alives). However, some socket APIs may not support this, as receiving 0 bytes is usually interpreted as meaning the connection has been closed. It is therefore recommended that transferring 0-byte block is avoided.

Indeed there are very few practical applications for using 0-byte blocks with X.25 - there is no normal need for keep-alive messages, as a connection closure can be detected without having to transmit anything (see below).

For this reason, it is usually best for an application to treat the reception of a 0-length block as an error, and to close the socket (thus clearing the virtual circuit).

Connection Closure

With TCP, you only normally get an indication that a connection has been broken (as opposed to being deliberately closed by the peer) when trying to send data. That's because of the connectionless nature of IP - there is no way of knowing that a connection remains active except by sending data. (There are some exceptions - the Microsoft TCP/IP stack in conjunction with Dial-Up Networking will cause connections to be closed if a Dial-Up link fails.)

X.25 and XOT, on the other hand, provides an immediate (or at least, immediate once the failure has been detected) notification of connection closure, even if the connection is idle - that's because the X.25 network protocol is connection oriented, and any failure within the network will cause all the virtual circuits carried by the failing link to be cleared.


Permanent Virtual Circuits

Using a PVC is like a making a client connection - the main difference to SVCs are:

  • the address - instead of specifying an X.25 DTE Address, the Logical Channel Number is used. In addition, if multiple X.25 links are configured, it's necessary to select the X.25 link.
  • it's necessary to handle X.25 Resets - these are done via extensions to the normal sockets API (and the FarSync API is different on Windows to Linux)

It's best to Reset a PVC when attaching to it - this can be done automatically by the FarSync X.25 Windows Sockets layer by specifying a socket option. In the case, the connect() operation does not complete until a response to the resulting Reset Request has been received.

Under Linux, however, in the same circumstances a Reset Request would have to be transmitted explicitly.

Data transfer on a PVC is otherwise similar to data transfer on an SVC. An application needs to be able to cope with the situation the remote application is no longer responding - in this case transmitted packets can cause the window to fill, resulting in further transmit requests blocking. In this circumstance, the only thing that can be done would be to Reset the PVC and try again, but of course if the remote application is still not responding then the same situation will recur.