z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


Allocating sockets in an iterative server program

z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
SC27-3660-00

The server must allocate a socket to provide an endpoint to which clients connect. All commands that pass a socket address must be consistent with the address family specified when the socket was opened.
  • If the socket was opened with an address family of AF_INET, then any command for that socket that includes a socket address must use an AF_INET socket address.
  • If the socket was opened with AF_INET6, then any command for that socket that includes a socket address must use an AF_INET6 socket address.
A socket is actually an index into a table of connections to the TCP/IP address space, so socket numbers are usually assigned in ascending order. In C, the programmer issues the socket() call to allocate a new socket, as shown in the following example:
s = socket(AF_INET, SOCK_STREAM, 0);
The socket function requires specification of the address family (AF_INET), the type of socket (SOCK_STREAM), and the particular networking protocol to be used. When 0 is specified, the TCP/IP address space automatically uses the protocol appropriate to the socket type specified. A new socket is allocated and returned.
An application must first get a socket descriptor using the socket() call, as seen in the following example. For a complete description, see socket().
int socket(int domain, int type, int protocol);
⋮
int s;
⋮
s = socket(AF_INET, SOCK_STREAM, 0);

The code fragment allocates socket descriptor s in the internet addressing family. The domain parameter is a constant that specifies the domain in which the communication is taking place. A domain is a collection of applications using a single addressing convention. The type parameter is a constant that specifies the type of socket; it can be SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW. The protocol parameter is a constant that specifies the protocol to be used. This parameter is ignored, unless type is set to SOCK_RAW. Passing 0 chooses the default protocol. If successful, the socket() call returns a positive integer socket descriptor.

The server obtains a socket by way of the socket call. You must specify the domain to which the socket belongs, and the type of socket you want.

Figure 1 lists the socket call() variables using the CALL API.
Figure 1. Socket call variables
*---------------------------------------------------------------*
* Variables used for the SOCKET call                            *
*---------------------------------------------------------------*
 01  afinet                         pic 9(8) binary value 2.
 01  soctype-stream                 pic 9(8) binary value 1.
 01  proto                          pic 9(8) binary value 0.
 01  socket-descriptor              pic 9(4) binary value 0.
*---------------------------------------------------------------*
* Get us a socket descriptor                                    *
*---------------------------------------------------------------*
   call 'EZASOKET' using soket-socket
     afinet
     soctype-stream
     proto
     errno
     retcode.
   if retcode < 0 then
     - process error -
   else
     Move retcode to socket-descriptor. 

The internet domain has a value of 2. A stream socket is requested by passing a type value of 1. The proto field is normally 0, which means that the socket API should choose the protocol to be used for the domain and socket type requested. In this example, the socket uses TCP protocols.

A socket descriptor representing an unnamed socket is returned from the socket() call. An unnamed socket has no port and no IP address information associated with it; only protocol information is available. The socket descriptor is a 2-byte binary field and must be passed on subsequent socket calls as such.

A socket is an inconvenient concept for a program because it consists of three different items: a protocol specification, a port number, and an IP address. To represent the socket conveniently, we use the socket descriptor.

The socket descriptor is not in itself a socket, but represents a socket and is used by the socket library routines as an index into the table of sockets owned by a given MVS™ TCP/IP client. On all socket calls that reference a specific socket, you must pass the socket descriptor that represents the socket with which you want to work.

Figure 2 lists the MVS TCP/IP socket descriptors.
Figure 2. MVS TCP/IP socket descriptor table
--------------------------------------------------------------------------
Socket Descriptor    Socket
0                    Our listen socket
1                    Our connected socket
--------------------------------------------------------------------------

The first socket descriptor assigned to your program is 0 (for a sockets extended program). If your program is written in C, socket descriptors 0, 1, and 2 are reserved for std.in, std.out and std.err, and the first socket descriptor assigned for your AF_INET sockets is numeral 3 or higher.

When a socket is closed, the socket descriptor becomes available; it is returned as a new socket descriptor representing a new socket in response to a succeeding request for a socket.

Note: In reference documentation, the socket descriptor is normally represented by a single letter: S, or by two letters: SD.

When you possess the socket descriptor, you can request the socket address structure from the socket programming interface by way of call getsockname(). A socket does not include both port and IP addresses until after a successful bind(), connect(), or accept() call has been issued.

If your socket program is capable of handling sockets simultaneously, you must keep track of your socket descriptors. Build a socket descriptor table inside of your program to store information related to the socket and the status of the socket. This information is sometimes needed, and can help in debug situations.

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014