═══ 1. About This Book ═══ The MPTS Sockets Programming Reference describes the Sockets application programming interface in an Multi-Protocol Transport Services (MPTS) Environment for Operating System/2 Software for the Internet (TCP/IP), local interprocess communication (Local IPC), and the NETBIOS communication domains. This interface allows you to write distributed or client/server applications in supported communication domains for programs to communicate across networks. ═══ 1.1. Who Should Use This Book ═══ This book is for application programmers who want to write socket applications to work with MPTS. You should also be familiar with the OS/2 operating system and know multitasking operating system concepts. ═══ 1.2. How This Book Is Organized ═══ This book contains the following topics:  Sockets General Programming Information provides an introduction to MPTS and describes general concepts for writing socket applications.  Sockets in the Internet Domain provides specific information for the use of sockets in the internet communication domain.  Sockets over Local IPC provides specific information for the use of sockets using local interprocess communication.  Sockets over NetBIOS provides specific information for the use of sockets in the NetBIOS communication domain.  Protocol-Independent C Sockets API provides descriptions and programming details for the protocol-independent sockets API.  TCP/IP Network Utility Routines provides descriptions and programming details for the TCP/IP network utility routines. ═══ 1.3. Where to Find More Information ═══ The following books or online references are suggested for additional reading and information. At your local bookstore:  TCP/IP Illustrated, Volume 1: The Protocols, W. Richard Stevens, Addison Wesley, 1994  TCP/IP Illustrated, Volume 2: The Implementation, Gary R. Wright and W. Richard Stevens, Addison Wesley, 1995  UNIX Network Programming, W. Richard Stevens, Prentice Hall, Englewood Cliffs, New Jersey, 1990  The C Programming Language: 2nd edition, Brian Kernighan and Dennis Ritchie, Prentice Hall, 1988  IBM TCP/IP Tutorial and Technical Overview  Internetworking with TCP/IP Volume I: Principles, Protocols, and Architectures  Internetworking with TCP/IP Volume II: Implementation and Internals  Introducing IBM's TCP/IP Products for OS/2, VM and MMVS  IBM TCP/IP Version 3.1 for OS/2: Programmer's Reference  IBM TCP/IP Version 3.1 for OS/2: User's Guide  IBM TCP/IP Version 3.1 for OS/2: Quick Reference Guide  IBM Local Area Network Techincal Reference  This book available on The Developer Connection for LAN Systems CD-ROM: - LAN Technical Reference IEEE 802.2 and NetBIOS APIs ═══ 2. Sockets General Programming Information ═══ This section contains technical information for planning, designing, and writing application programs that use the sockets application programming interface (API) of MPTS in an OS/2 environment. This section contains information on the following topics:  MPTS  Programming with Sockets  Network-Byte Order  Multithreading Considerations  Typical Socket Session Diagrams  Using Socket Calls  Porting a Sockets API Application  Software Requirements and Toolkit Files  Compiling and Linking a Sockets Application ═══ 2.1. MPTS ═══ MPTS provides a solution to interconnect applications across networks. MPTS provides a 32-bit sockets API for Internet (TCP/IP), local interprocess communication (Local IPC), and NetBIOS communication domains. Network Services sockets is based on the Berkeley Software Distribution (BSD) version 4.3 sockets implementation. The sockets API allows you to write distributed or client/server applications in supported communication domains to allow applications to communicate across networks. In addition, the interface allows interprocess communication within the same workstation. Applications can have full network access by using the sockets API. An existing sockets application can usually be made to run in another communications domain by modifying the communications domain section and the networking addressing parameters used by the application. The application must then be recompiled and relinked. Components of Network Services shows a functional relationship between the application program and the MPTS Sockets API, supported communication domains, and supported network adapters. Note that the SNA APIs are not part of the sockets programming API and that information on the SNA communication domain is not discussed in any portion of this book. Components of Network Services ═══ 2.2. Programming with Sockets ═══ The sockets API allows an application to communicate across networks with other applications. You can, for example, make use of the sockets interface when you write a client application that may communicate with a server application running on the same or another workstation. To use sockets, you must know the C programming language. The MPTS OS/2 sockets API provides a standard interface to all supported communication domains: Internet, Local IPC, and NetBIOS. MPTS OS/2 supports four socket types: datagram, raw, sequenced packet, and stream. Each communication domain supports certain socket types. Refer to Socket Types for additional information. ═══ 2.2.1. What is a Socket? ═══ A socket is an endpoint for communication. From an application program perspective, it is a resource allocated by MPTS. It is represented by an integer called a socket descriptor. A pair of sockets, one in each of two tasks, is used for interprocess communication (IPC) between them, on a single workstation or different workstations. Sockets are full-duplex, which means that data can be transmitted and received simultaneously. Each socket is created for a particular communication domain and socket type. Communication can occur between applications using the same socket type within the same communications domain only. The sockets API is designed to provide applications with access to the network while hiding the details of the physical network. You choose a socket type (refer to Socket Types) that reflects the communication characteristics that you want. For example, stream sockets offers a reliable method of data transmission without message boundaries. ═══ 2.2.2. Socket Protocol Families and Supported Communication Domains ═══ Communication domains are specified in MPTS as protocol families. Specifying the protocol family identifies the underlying network protocol used during communications. All servers in the same protocol family understand and use the same scheme of addressing socket endpoints. The protocol families are defined in the header file and are listed in Communication Domains Supported. ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 1. Communication Domains Supported │ ├────────────────┬────────────────────┬────────────────────┬──────────────────┤ │ │ ADDRESS FAMILY │ │ │ │ COMMUNICATION │ #DEFINE IN │ SUPPORTED PROTO- │ SUPPORTED SOCKET │ │ DOMAIN │ │ COLS │ TYPES │ ├────────────────┼────────────────────┼────────────────────┼──────────────────┤ │ Internet │ AF_INET │ ICMP, IGMP, IP, │ Datagram, Raw, │ │ │ │ TCP, UDP │ Stream │ ├────────────────┼────────────────────┼────────────────────┼──────────────────┤ │ Local IPC │ AF_OS2, AF_UNIX, │ Local IPC │ Datagram, Stream │ │ │ or AF_LOCAL │ │ │ ├────────────────┼────────────────────┼────────────────────┼──────────────────┤ │ NetBIOS │ AF_NETBIOS or │ NetBIOS │ Datagram, │ │ │ AF_NB │ │ Sequenced Packet │ └────────────────┴────────────────────┴────────────────────┴──────────────────┘ As Communication Domains Supported indicates, some socket types can be used in more than one communications domain. Refer to Socket Types for additional information on socket types. Default Protocols lists the default protocols for each communication domain-socket type that is supported. ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 2. Default Protocols │ ├──────────────┬──────────────────┬──────────────────────┬────────────────────┤ │ COMMUNI- │ │ DEFAULT PROTOCOL │ │ │ CATION │ │ #DEFINE IN │ OTHER PROTOCOLS │ │ DOMAIN │ SOCKET TYPE │ │ SUPPORTED │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ Internet │ Datagram │ UDP (IPPROTO_UDP) │ │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ │ Raw │ Raw IP (IPPROTO_RAW) │ ICMP │ │ │ │ │ (IPPROTO_ICMP) │ │ │ │ │ IGMP │ │ │ │ │ (IPPROTO_IGMP) │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ │ Stream │ TCP (IPPROTO_TCP) │ │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ Local IPC │ Datagram │ none (0) │ │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ │ Stream │ none (0) │ │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ NetBIOS │ Datagram │ NetBIOS (NBPROTO_NB) │ │ ├──────────────┼──────────────────┼──────────────────────┼────────────────────┤ │ │ Sequenced Packet │ NetBIOS (NBPROTO_NB) │ │ └──────────────┴──────────────────┴──────────────────────┴────────────────────┘ ═══ 2.2.3. Socket Address Families ═══ An address family is a specific address format that conforms to the rules of the communication domain that the address family is used in. The address families that are supported by MPTS are defined in the header file and are listed in Socket Address Families. ┌────────────────────────────────────────────────────────────────────────────────┐ │ Table 3. Socket Address Families │ ├────────────┬────────────────────────────────────────────┬──────────────────────┤ │ │ │ ADDRESS FAMILY │ │ ADDRESS │ │ #DEFINE IN │ │ FAMILY │ DESCRIPTION │ │ ├────────────┼────────────────────────────────────────────┼──────────────────────┤ │ Internet │ Defines addresses in the Internet Protocol │ AF_INET │ │ │ version 4 address format. │ │ ├────────────┼────────────────────────────────────────────┼──────────────────────┤ │ Local IPC │ Defines addresses in the Local IPC address │ AF_OS2, AF_UNIX, or │ │ │ format. │ AF_LOCAL │ ├────────────┼────────────────────────────────────────────┼──────────────────────┤ │ NetBIOS │ Defines addresses in the NetBIOS address │ AF_NETBIOS or AF_NB │ │ │ format. │ │ └────────────┴────────────────────────────────────────────┴──────────────────────┘ ═══ 2.2.4. Connection Modes ═══ A connection mode refers to an established logical channel for the transmission of data between two application programs. The MPTS OS/2 sockets API supports two connection modes:  Connection-oriented  Connectionless The connection-oriented mode requires that a logical connection be established between two applications before data transfer or communication can occur. Applications encounter some overhead during the connection establishment phase as the applications negotiate the connection request. This mode is useful for applications that use long datastream transmissions or require reliable transmissions of data. The term connected refers to two endpoints that have an established logical connection between them. Stream and sequenced packet socket types use the connection-oriented mode and are always connected. The connectionless mode does not require a logical connection to allow communication between applications. Rather, individual messages are transmitted independently from one application to another application. Each message must contain the data and all information required for delivery of the message to its destination. Normally, datagram and raw socket types use the connectionless mode. See "Datagram or raw sockets".. ═══ 2.3. Socket Types ═══ Each socket has an associated type, which describes the semantics of communication for the socket. The socket type determines the socket communication properties such as reliability, ordering, and prevention of duplication of messages. The MPTS OS/2 sockets API supports communications between applications using the same socket type only. The socket type is passed as a parameter to the socket() call. Socket Types summarizes the attributes and features of each socket type. ═══ 2.3.1. Stream Sockets ═══ Stream sockets model duplex byte streams and define a reliable connection-oriented service. Data is sent without errors or duplication and is received in the same order as it was sent. Flow control is built in to avoid data overruns. No boundaries are imposed on the data; it is considered to be a stream of bytes. Stream sockets are connected sockets and are either active or passive. Active sockets are used by clients who initiate connection requests with connect(). Passive sockets are used by servers to accept connection requests with the listen() and accept() calls. Receiving data from any address is supported. After a connection has been established between stream sockets, any of these data transfer calls can be used: send() and recv() sendto() and recvfrom() sendmsg() and recvmsg() writev() and readv() Usually, a send()-recv() pair is used for sending data on stream sockets. ═══ 2.3.2. Sequenced Packet Sockets ═══ Sequenced packet sockets define a reliable connection-oriented service. Data is sent without error or duplication and is received in the same order as it was sent. Flow control is built in to avoid data overruns. Every sequenced packet is sent and received as a complete record. Receiving data from any address is supported. After a connection has been established between sequenced packet sockets, any of these data transfer calls can be used: send() and recv() sendto() and recvfrom() sendmsg() and recvmsg() writev() and readv() Usually, a send()-recv() pair is used for sending data on sequenced packet sockets. ═══ 2.3.3. Datagram Sockets ═══ Datagram sockets provide connectionless message exchange with no guarantee of delivery. Data can be lost or duplicated, and datagrams can arrive out of order. Datagrams are sent and received as complete records. The size of a datagram is limited to the size that an underlying protocol supports. A datagram socket operating in connectionless mode can exchange datagrams using the sendto() and recvfrom() calls. Receiving data from any address is supported. Datagram sockets are connectionless mode sockets by default. If an application program is using datagram sockets and calls connect() fully specifying the destination address, the sockets are considered to be connected. The application program can then use the other data transfer calls send() and recv() or writev() and readv(). This method of data transfer stays in effect until connect() is called again with a different destination address. Refer to "Datagram or raw sockets". for additional information. Datagram sockets can be used to send broadcast messages in the internet and NetBIOS communications domains. For the Internet domain, the broadcast function is dependent on the address class and whether subnets are being used. The constant INADDR_BROADCAST, defined in the file, can be used to broadcast to the primary network if the primary network is configured to support broadcast. These comments are defined and are NB_UNIQUE, NB_GROUP, and NB_BROAD. respectively. For the NetBIOS domain, the address format has a type field that specifies whether the address is unique, multicast, or broadcast. ═══ 2.3.4. Raw Sockets ═══ Raw sockets provide connectionless message exchange with the same data transfer semantics as previously described for datagram sockets. You can use raw sockets to directly access the protocol specified in the socket() call, such as the Internet Protocol (IP), the Internet Control Message Protocol (ICMP), or the Internet Group Management Protocol (IGMP). Raw sockets are often used for testing new protocol implementations or gaining access to some of the more advanced facilities of an existing protocol. Raw sockets are connectionless mode sockets by default. Raw sockets can be connected if connect() is called to specify the destination address. Refer to "Datagram or raw sockets". for additional information. ═══ 2.3.5. Socket Types Summary Tables ═══ Socket Types summarizes many of the attributes and features of supported socket types. ┌────────────────────────────────────────────────────────────────────────────────┐ │ Table 4. Socket Types │ ├───────────┬────────────────────┬─────────────────┬───────────┬─────────────────┤ │ │ │ │ CON- │ │ │ SOCKET │ #DEFINE IN │ │ NECTION │ PRIMARY │ │ TYPE │ │ DOMAINS │ ORIENTED? │ SOCKET CALLS │ ├───────────┼────────────────────┼─────────────────┼───────────┼─────────────────┤ │ Stream │ SOCK_STREAM │ INET, Local │ yes │ send - recv │ │ │ │ IPC, NetBIOS │ │ │ ├───────────┼────────────────────┼─────────────────┼───────────┼─────────────────┤ │ Sequenced │ SOCK_SEQPACKET │ NetBIOS │ yes │ send - recv │ │ Packet │ │ │ │ │ ├───────────┼────────────────────┼─────────────────┼───────────┼─────────────────┤ │ Datagram │ SOCK_DGRAM │ INET, Local │ no (*) │ sendto - │ │ │ │ IPC, NetBIOS │ │ recvfrom(*) │ ├───────────┼────────────────────┼─────────────────┼───────────┼─────────────────┤ │ Raw │ SOCK_RAW │ INET │ no (*) │ sendto - │ │ │ │ │ │ recvfrom(*) │ ├───────────┴────────────────────┴─────────────────┴───────────┴─────────────────┤ │ NOTE: (*) unless the application has called connect() for the socket. In │ │ this case, the socket is CONNECTED. Refer to Connection Modes for additional │ │ information. │ └────────────────────────────────────────────────────────────────────────────────┘ ═══ 2.3.6. Guidelines for Using Socket Types ═══ If you are communicating with an existing application, you must use the same socket type and the same communication domain as the existing application. Raw sockets have a special purpose of interfacing directly to the underlying protocol layer. If you are writing a new protocol on top of Internet Protocol (IP) or wish to use the Internet Control Message Protocol (ICMP) or the Internet Group Management Protocol (IGMP), then you must use a raw sockets. You should consider the following factors in choosing a socket type for new applications:  Reliability Stream sockets provide the most reliable connection. Connectionless mode datagram and raw sockets are unreliable because packets can be discarded, duplicated, or received out of order. This may be acceptable if the application does not require reliability, or if the application implements the reliability on top of the sockets API. The trade-off is the increased performance available over stream sockets.  Performance The overhead associated with reliability, flow control, packet reassembly, and connection maintenance degrades the performance of stream sockets so that stream sockets do not perform as well as datagram sockets acting in a connectionless mode.  Amount of data to be transferred Datagram sockets impose a limit on the amount of data transferred, depending on the protocol. As the amount of data in a single transaction increases, it is preferable to use stream sockets. ═══ 2.3.7. Socket Addresses and Data Structure Format ═══ A socket can be bound to a unique local name with the bind() call with an address so that tasks can connect to it. The socket address format conforms to the rules governing network addresses for each communication domain. For example, in the Internet communication domain, a host address is a 32-bit value that represents one of the ways Internet addresses can be encoded. Each communication domain has different rules for valid socket names and interpretation of names. A socket address is defined by the following sockaddr structure, which is found in the header file: struct sockaddr { u_char sa_family; /* address family */ char sa_data[14]; /* address value */ }; The sa_family field contains the address family. The sa_data field is different for each address family. Each address family defines its own structure, which is overlaid on the sockaddr structure. Socket address structures for the Internet, Local IPC, and NetBIOS communication domains (sockaddr_in, sockaddr_un, sockaddr_nb) are described in "Addressing within an Internet Domain", Local IPC Address Format, and NetBIOS Address Format. ═══ 2.4. Multithreading Considerations ═══ The sockets and network utility routines are completely re-entrant. Multiple threads of an application can call any socket call. ═══ 2.5. Typical Socket Session Diagrams ═══ The following figures show a graphical representation for the general sequence of socket calls needed to provide communication between applications for supported socket types. This basic sequence is the same for each supported communication domain for all supported socket types. This means that a programmer can modify the communications domain selection and the networking addressing parameters of an existing sockets program, recompile and relink, and the program can be run in another domain. This also allows programs that use sockets in multiple domains to be easily constructed. A Typical Stream or Sequenced Packet Socket Session There is an alternative to the serialized sequence in A Typical Stream or Sequenced Packet Socket Session. The server can call accept() to create a new thread to handle this new socket. Using the original thread, the server can then call accept() again and begin waiting for more requests. A Typical Datagram Socket Session ═══ 2.6. Using Socket Calls ═══ A detailed description of using the basic socket calls follows. These examples show communication between applications in the Internet communication domain using stream sockets. Additional information for other supported domains can be found in Sockets over Local IPC and Sockets over NetBIOS. 1. An application must get a socket descriptor using the socket() call, as in An Application Using the socket() Call. For a more detailed description, see socket(). An Application Using the socket() Call int socket(int domain, int type, int protocol); /* extracted from sys\socket.h */ int s; . . . s = socket(AF_INET, SOCK_STREAM, 0); In this example, the socket() call allocates a socket descriptor s in the Internet communication domain. The communication domain is specified in the domain parameter. The domain is specified with one of the supported protocol families. This example specifies the protocol family AF_INET. The type parameter is a constant that specifies the type of socket. For the internet communication domain, this can be SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW. The protocol parameter is a constant that specifies which protocol to use. Passing 0 chooses the default protocol for the specified socket type. Refer to Default Protocols for information on default protocols. If successful, socket() returns a non-negative integer socket descriptor. After an application has a socket descriptor, it can explicitly bind() a unique name to the socket, as in An Application Using the bind() Call. An Application Using the bind() Call int rc; int s; struct sockaddr_in myname; int bind(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ /* clear the structure */ memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_addr.s_addr = inet_addr("129.5.24.1"); /* specific interface */ myname.sin_port = htons(1024); . . . rc = bind(s, (struct sockaddr *) &myname, sizeof(myname)); For a server in the Internet domain to be able to use listen() for connections on a stream socket or use recvfrom() on a datagram socket, the server must first use the bind() call to bind the socket to a specific address family and port. This example binds myname to socket s. Note that the sockaddr_in structure should be cleared before calling bind(). For a more detailed description, see bind(). For information on the sockaddr_in structure, see Internet Address Formats. The unique name myname specifies that the application uses an internet address family (AF_INET) at internet address 129.5.24.1, and is bound to port 1024. The example in An Application Using the bind() Call shows two useful network utility routines:  inet_addr() takes an internet address in dotted-decimal form and returns it in network-byte order. For a more detailed description, see inet_addr().  htons() takes a port number in host-byte order and returns the port in network-byte order. For a more detailed description, see htons(). A bind() Call Using the getservbyname() Call shows how the bind() call on the server side uses the network utility routine getservbyname() to find a well-known port number for a specified service from the ETC\SERVICES file. For more information on well-known ports, see Ports. A bind() Call Using the getservbyname() Call also shows the use of the internet address value INADDR_ANY. This is the value generally used on a socket bind() call. It binds the socket to all internet addresses available on the local machine, without requiring the program to know the local internet address. (The code fragment in An Application Using the bind() Call runs successfully only on the machine with internet address 192.5.24.1). If a host has more than one internet address (that is, if it is multihomed host), messages sent to any of the addresses are deliverable to a socket bound to INADDR_ANY. A bind() Call Using the getservbyname() Call int rc; int s; struct sockaddr_in myname; int bind(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ struct servent *sp; . . . sp = getservbyname("login","tcp"); /* get application specific */ /* well-known port */ . . . /* clear the structure */ memset(&myname,0,sizeof(myname)); myname.sin_family = AF_INET; myname.sin_addr.s_addr = INADDR_ANY; /* any interface */ myname.sin_port = sp->s_port; . . . rc = bind(s,(struct sockaddr *)&myname,sizeof(myname)); ═══ 2.6.1. Indicating Readiness to Accept Connections ═══ After binding a name to a socket, a server using stream sockets must indicate readiness to accept connections from clients. The server does this with the listen() call, as illustrated in the example in An Application Using the listen() Call. An Application Using the listen() Call int s; int backlog; int rc; int listen(int s, int backlog); /* extracted from sys\socket.h */ . . . rc = listen(s, 5); The listen() call is used to indicate the server is ready to accept connections. In this example, a maximum of five connection requests can be queued for the server. Additional requests are ignored. For a more detailed description, see listen(). ═══ 2.6.2. Requesting a Connection ═══ Clients using stream sockets call connect() to request a connection as shown in An Application Using the connect() Call. An Application Using the connect() Call int s; struct sockaddr_in servername; int rc; int connect(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ . . . memset(&servername, 0,sizeof(servername)); servername.sin_family = AF_INET; servername.sin_addr.s_addr = inet_addr("129.5.24.1"); servername.sin_port = htons(1024); . . . rc = connect(s, (struct sockaddr *) &servername, sizeof(servername)); The connect() call attempts to connect socket s to the server with the name supplied in servername. This could be the server that was used in the previous bind() example. With stream sockets the caller optionally blocks until the connection request is added to the queue of incoming connections for the listening socket. On successful return from connect(), the socket s is associated with the connection to the server. Refer to ioctl() for additional information about determining blocking and nonblocking behavior. Note that the sockaddr_in structure should be cleared before calling connect(). For a more detailed description, see connect(). An Application Using the gethostbyname() Call int s; struct sockaddr_in servername; char *hostname = "serverhost"; int rc; int connect(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ struct hostent *hp; . . . hp = gethostbyname(hostname); /* clear the structure */ memset(&servername,0,sizeof(servername)); servername.sin_family = AF_INET; servername.sin_addr.s_addr = *((u_long *)hp->h_addr); servername.sin_port = htons(1024); . . . rc = connect(s,(struct sockaddr *)&servername,sizeof(servername)); An Application Using the gethostbyname() Call shows an example of using the gethostbyname() network utility routine to find out the internet address of serverhost from the name server or the ETC\HOSTS file. ═══ 2.6.3. Accepting a Connection Request ═══ Servers using stream sockets accept a connection request with the accept() call, as shown in An Application Using the accept() Call. An Application Using the accept() Call int clientsocket; int s; struct sockaddr clientaddress; int addrlen; int accept(int s, struct sockaddr *addr, int *addrlen); /* extracted from sys\socket.h */ . . . addrlen = sizeof(clientaddress); . . . clientsocket = accept(s, &clientaddress, &addrlen); If connection requests are not pending on socket s, the accept() call blocks the server unless ioctl() has been called. Refer to ioctl() for additional information about determining blocking and nonblocking behavior. When a connection request is accepted on socket s, the name of the client and length of the client name are returned, along with a new socket descriptor. The new socket descriptor is associated with the client that initiated the connection and socket s is again available to accept new connections. For a more detailed description, see accept(). ═══ 2.6.4. Transferring Data with Connected Sockets ═══ There are several sockets API calls available to clients and servers for data transfer. The readv() and writev(), and send() and recv() calls can be used on connected sockets. The sendto() and recvfrom() calls can be used on both connected and unconnected sockets. An Application Using the send() and recv() Calls int bytes_sent; int bytes_received; char data_sent[256] = "data to be sent on connected socket"; char data_received[256]; int send(int socket, char *buf, int buflen, int flags); /* extracted from sys\socket.h */ int recv(int socket, char *buf, int buflen, int flags); /* extracted from sys\socket.h */ int s; . . . bytes_sent = send(s, data_sent, sizeof(data_sent), 0); . . . bytes_received = recv(s, data_received, sizeof(data_received), 0); The example in An Application Using the send() and recv() Calls shows an application sending data on a connected socket and receiving data in response. The flags field can be used to specify additional options to send() or recv(), such as sending out-of-band data. For additional information, see send() and recv(). ═══ 2.6.5. Transferring Data with Unconnected Sockets ═══ If the socket is not connected, additional addressing information must be passed using sendto() and can be optionally returned using recvfrom(). An example of using the sendto() and recvfrom() calls is shown in An Application Using the sendto() and recvfrom() Calls. An Application Using the sendto() and recvfrom() Calls int bytes_sent; int bytes_received; char data_sent[256] = "data to be sent using sendto()"; char data_received[256]; struct sockaddr_in to; struct sockaddr from; int addrlen; int sendto(int socket, char *buf, int buflen, int flags, struct sockaddr *addr, int addrlen); /* extracted from sys\socket.h */ int recvfrom(int socket, char *buf, int buflen, int flags, struct sockaddr *addr, int *addrlen); /* extracted from sys\socket.h */ int s; . . . memset(&to, 0, sizeof(to)); to.sin_family = AF_INET; to.sin_addr.s_addr = inet_addr("129.5.24.1"); to.sin_port = htons(1024); . . . bytes_sent = sendto(s, data_sent, sizeof(data_sent), 0, (struct sockaddr *) &to, sizeof(to)); . . . addrlen = sizeof(from); /* must be initialized */ bytes_received = recvfrom(s, data_received, sizeof(data_received), 0, &from, &addrlen); The sendto() and recvfrom() calls take additional parameters that allow the caller to specify the recipient of the data or to be notified of the sender of the data. See recvfrom(), and sendto(), for more information about these additional parameters. ═══ 2.6.6. Transferring Data with Scatter/Gather Features ═══ The writev() and readv() calls, shown in An Application Using the writev() and readv() Calls, provide the additional features of scatter/gather read/write of data. Scattered data can be located in multiple data buffers. The writev() call gathers the scattered data and sends it. The readv() call receives data and scatters it into multiple buffers. An Application Using the writev() and readv() Calls int s, iovcnt, bytes_sent, bytes_read; struct iovec iov[3]; char header_out[] = "This is the header"; char data_out[] = "This is the data"; char trailer_out[] = "This is the trailer"; char header_in[18]; char data_in[16]; char trailer_in[19]; . . . /* Put data in buffers */ iovcnt = 3; iov[0].iov_base = header_out; iov[0].iov_len = sizeof(header_out); iov[1].iov_base = data_out; iov[1].iov_len = sizeof(data_out); iov[2].iov_base = trailer_out; iov[2].iov_len = sizeof(trailer_out); /* Send the message in buffers to the server */ bytes_sent = writev(s, iov, iovcnt); . . . iov[0].iov_base = header_in; iov[0].iov_len = sizeof(header_in); iov[1].iov_base = data_in; iov[1].iov_len = sizeof(data_in); iov[2].iov_base = trailer_in; iov[2].iov_len = sizeof(trailer_in); /* Read the message in buffers */ bytes_read = readv(s, iov, iovcnt); ═══ 2.6.7. Transferring Data with Multiple Sockets ═══ Applications can handle multiple sockets. In such situations, you can use the select() call to determine the sockets that have data to be read, those that are ready for data to be written, and the sockets that have pending exception conditions. If the timeout parameter is positive, select() waits up to this amount of time for at least one socket to become ready on the indicated conditions. This is useful for applications servicing multiple connections that cannot afford to block and are waiting for data on one connection. An Application Uses the BSD Version select() Call #define BSD_SELECT fd_set readsocks; fd_set writesocks; fd_set exceptsocks; struct timeval timeout; int number_of_sockets; int number_found; . . . /* set bits in read write except bit masks. To set mask for a descriptor s use * readsocks |= fd_set(s); * * set number of sockets to be checked * number_of_sockets = x; */ . . . number_found = select(number_of_sockets, &readsocks, &writesocks, &exceptsocks, &timeout); In this example, the application indicates the sockets to be checked for readability or readiness for writing. ═══ 2.6.8. Using Asynchronous Socket Operations ═══ In addition to select(), applications can use the ioctl() call to help perform asynchronous (nonblocking) socket operations. An example of the use of the ioctl() call is shown in An Application Using the ioctl() Call. An Application Using the ioctl() Call int s; int bytes_received; int dontblock; char buf[256]; int rc; int ioctl(int s, int command, char *command_data, int datasize); /* extracted from sys\socket.h */ . . . dontblock = 1; . . . rc = ioctl(s, FIONBIO, (char *) &dontblock, sizeof(dontblock)); . . . bytes_received = recv(s, buf, sizeof(buf), 0); if (bytes_received == -1) { if (sock_errno() == SOCEWOULDBLOCK) /* data is not present */ else /* error occurred */ } else /* bytes_ received indicates amount of data received in buf */ This example causes the socket s to be placed in nonblocking mode. When this socket is passed as a parameter to calls that would block, such as recv() when data is not present, it causes the call to return with an error code, and sets the error value to SOCEWOULDBLOCK. Setting the mode of the socket to be nonblocking allows an application to continue processing without becoming blocked. For a more detailed description, see ioctl(). ═══ 2.6.9. Deallocating a Socket Descriptor ═══ The socket descriptor s is deallocated with the soclose() call. For a more detailed description, see soclose(). An example of the soclose() call is shown in An Application Using the soclose() Call. An Application Using the soclose() Call int soclose(int s); /* extracted from sys\socket.h */ . . . /* close the socket */ soclose(s); . . . ═══ 2.7. Porting a Sockets API Application ═══ MPTS OS/2 sockets is based on the Berkeley Software Distribution Version 4.3 sockets implementation.  Sockets are not OS/2 Warp files or devices. Socket descriptors have no relationship to OS/2 Warp file handles. Therefore, file-related calls such as read(), write(), and close() do not work for sockets. Use the recv(), send(), and soclose() functions instead.  To access MPTS return values, add the following include statement: #include Error codes set by the MPTS OS/2 sockets API are not made available using the global errno variable. Instead, error codes are accessed by using the sock_errno() API described in sock_errno(). Use psock_errno(), instead of perror(), to write a short error message on the standard error device describing the last error encountered during a call to a socket library function. This is intended to obtain per-thread error codes in a multithreaded application environment and to avoid problems with conflicting errno constants defined by some compilers. For compatibility with Berkeley Software Distribution (BSD), an application can choose to define: #define errno sock_errno() #define perror psock_errno Place these definitions after # include . If a source file includes code that checks errno for both OS/2 Warp socket and OS/2 Warp nonsocket functions, this mechanism cannot be used. BSD-style error checking is as follows: rt = recv(s, buf, sizeof(buf), 0); if (rt == -1 && errno == SOCEWOULDBLOCK) {...} if (recv(s, buf, sizeof(buf), 0) < 0) { perror("Recv()"); exit(1); } The preferred OS/2 Warp-style error checking is as follows: rt = recv(s, buf, sizeof(buf), 0); if (rt == -1 && sock_errno() == SOCEWOULDBLOCK) {...} if (recv(s, buf, sizeof(buf), 0) < 0) { psock_errno("Recv()"); exit(1); } Error constants consistent with BSD sockets are provided for compatibility purposes; your application can use the error constant EWOULDBLOCK instead of SOCEWOULDBLOCK. Refer to Socket Error Return Code Constants, or the file for definitions of error constants.  Unlike the BSD select() call, you cannot use the OS/2 select() call to wait for activity on devices other than sockets. See select() for more information.  The ioctl() interface differs slightly from the current BSD ioctl() implementation. For example, IBM has added a lendata parameter, which the current BSD ioctl() implementation does not require. Other functions of the IBM ioctl() call also differ from the current BSD ioctl() implementation in some cases. In addition, the getsockopt() and setsockopt() provides support for additional protocol-specific options. For more information, see: ioctl() getsockopt() setsockopt() Mapping NetBIOS Control Block (NCB) Calls to Socket Calls The following lists the NCB calls and the appropriate socket calls to map to. ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Table 5. NCB Calls to Socket Calls Mapping │ ├────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB CALL │ SOCKET CALL(S) │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.ADD.GROUP.NAME │ bind() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.ADD.NAME │ bind() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.CALL │ connect() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.CANCEL │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.CHAIN.SEND │ sendmsg(), writev() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.CHAIN.SEND.NO.ACK │ sendmsg(), writev() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.DELETE.NAME │ soclose() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.FIND.NAME │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.GATHER.SEND │ sendmsg(), writev() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.HANG.UP │ soclose() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.LAN.STATUS.ALERT │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.LISTEN │ listen() + accept() * │ ├────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────┤ │ *: After you call listen() and accept(), you can call accept() multiple times without calling listen() again. │ │ This is functionally equivalent to multiple calls of NCB.LISTEN. For example, if you call NCB.LISTEN three times, │ │ the mapping would be: │ │ │ │ NCB.LISTEN #1 ───> listen() + accept() │ │ NCB.LISTEN #2 ───> accept() │ │ NCB.LISTEN #3 ───> accept() │ ├────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.RECEIVE │ readv(), recv(), recvfrom(), recvmsg() ** │ ├────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────┤ │ **: With NCB.RECEIVE calls, you must issue a receive call before the send call is issued. With the socket read │ │ and receive calls, you can issue the send and receive calls in any order. │ ├────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.RECEIVE.ANY │ readv(), recv(), recvfrom(), recvmsg() ** │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.RECEIVE.BROADCAST.DATAGRAM │ recvfrom(), recvmsg() ** │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.RECEIVE.DATAGRAM │ recvfrom(), recvmsg() ** │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.RESET │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SCATTER.RECV.ANY │ readv(), recvmsg() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SEND │ send(), sendmsg(), sendto(), writev() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SEND.BROADCAST.DATAGRAM │ sendmsg(), sendto() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SEND.DATAGRAM │ connect() + send(), sendmsg(), sendto() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SEND.NOACK │ send(), sendmsg(), sendto(), writev() │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.SESSION.STATUS │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.STATUS │ N/A │ ├────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────┤ │ NCB.UNLINK │ N/A │ └────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────┘ In general, select() is used when a no-wait NCB call is simulated. For example, for a no-wait NCB.CALL, a connect() would be issued and then a select() to determine when the connection is made successfully. ═══ 2.8. Software Requirements and Toolkit Files ═══ This section describes the software requirements for running the MPTS code and also lists the socket header and library files. ═══ 2.8.1. Software Requirements ═══ You must have the following software installed on your system:  OS/2 Warp  OS/2 Warp MPTS  IBM C Set/2 If installing MPTS on top of a previous version of MPTS OR NTS/2, be aware that the Toolkit files for developers are no longer installed. To unpack the Socket files into the desired directory, insert MPTS Diskette 5 into drive A: on the code server and type the following command: PKUNZIP2 -d A:\TOOLKIT\MPTNTK.ZIP The following example places the MPTS developer toolkit files in drive C: PKUNZIP2 -d A:\TOOLKIT\MPTNTK.ZIP C:\ Note: If MPTS is not installed on the workstation where you are unpacking the MPTS Toolkit, you must copy the PKUNZIP2.EXE program from the root directory of MPTS Diskette 1 into a directory that is in the current path. ═══ 2.8.2. Header and Library Files ═══ This section lists the header and library files that are installed from the Socket Toolkit to your workstation. ═══ 2.8.2.1. Header Files ═══ The following are the socket application header files . ┌───────────────────────────────────────────────────────────────────────────┐ │ Table 6. Header Files │ ├──────────────────────┬────────────────────────────────────────────────────┤ │ HEADER FILE │ DESCRIPTION │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ ARPA\NAMESER.H │ IP name server definition │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NET\IF.H │ TCP/IP network interface definition │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NET\IF_ARP.H │ TCP/IP ARP protocol definition │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NET\ROUTE.H │ TCP/IP routing table definition │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETDB.H │ TCP/IP network utility definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETNB\NB.H │ NetBIOS address structure definition │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NERRNO.H │ MPTS error code definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETINET\IN.H │ IP constants and structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETINET\IF_ETHER.H │ Ethernet structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETINET\IN_SYSTM.H │ Internetwork definitions for kernel │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETINET\IP.H │ IP definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETINET\IP_ICMP.H │ ICMP definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ CRYPT.H │ Crypt structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ FTPAPI.H │ FTP structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ GRP.H │ Group definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ NETLIB.H │ NETLIB definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ PWD.H │ Password structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYSLOG.H │ System log definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ RESOLV.H │ IP name resolution definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYS\IOCTL.H │ Input/output control definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYS\SELECT.H │ BSD_SELECT definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYS\SOCKET.H │ Socket definitions and structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYS\TIME.H │ Time_val structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ SYS\UN.H │ Local IPC structures │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ TYPES.H │ Data type definitions │ ├──────────────────────┼────────────────────────────────────────────────────┤ │ UTILS.H │ TCP/IP utility routine definitions │ └──────────────────────┴────────────────────────────────────────────────────┘ ═══ 2.8.2.2. Library Files ═══ Library Files and DLL Files and Their Application list library files an application must link to. ┌─────────────────────────────────────────────────────────────────────┐ │ Table 7. Library Files │ ├────────────────┬────────────────────────────────────────────────────┤ │ LIBRARY FILE │ DESCRIPTION │ ├────────────────┼────────────────────────────────────────────────────┤ │ SO32DLL.LIB │ Linkable library containing the 32-bit protocol- │ │ │ independent socket entry point descriptions │ ├────────────────┼────────────────────────────────────────────────────┤ │ TCP32DLL.LIB │ Linkable library containing the 32-bit │ │ │ TCP/IP-specific network utility routine entry │ │ │ point descriptions │ ├────────────────┼────────────────────────────────────────────────────┤ │ TCPIPDLL.LIB │ Linkable library containing 16-bit TCP/IP-specific │ │ │ network routine entry point descriptions │ └────────────────┴────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────┐ │ Table 8. DLL Files and Their Application │ ├────────────────┬────────────────────────────────────────────────────┤ │ DLL FILE │ APPLICATION │ ├────────────────┼────────────────────────────────────────────────────┤ │ SO32DLL.DLL │ Dynamically linked library containing the 32-bit │ │ │ protocol-independent socket calls │ ├────────────────┼────────────────────────────────────────────────────┤ │ TCP32DLL.DLL │ Dynamically linked library containing the 32-bit │ │ │ TCP/IP specific network utility routines │ ├────────────────┼────────────────────────────────────────────────────┤ │ TCCPIPDLL.DLL │ dynamically linked library containing the 16-bit │ │ │ TCP/IP-specfic newtork utility routines │ └────────────────┴────────────────────────────────────────────────────┘ Note: All DLL files must reside in a directory listed in the LIBPATH system environment variable for the program to run. ═══ 2.9. Compiling and Linking a Sockets Application ═══ The following steps describe the compiling and linking procedures for a sockets application using the C++ compiler. Set your environment variables to find the following:  Executable programs  Link libraries  Header files You can set the environment variables interactively, or you can include them in your CONFIG.SYS file. The following is an example of the entries you may have in your CONFIG.SYS file. SET PATH=C:\IBMC\BIN;%PATH% SET DPATH=C:\IBMC\LOCALE;C:\IBMC\HELP;%DPATH% SET LIB=C:\IBMC\LIB;C:\MPTN\LIB;%LIB% SET INCLUDE=C:\IBMC\INCLUDE;C:\MPTN\INCLUDE;%INCLUDE% SET HELP=C:\IBMC\HELP;%HELP% SET BOOKSHELF=C:\IBMC\HELP;%BOOKSHELF% SET TZ=EST5EDT,0,0,0,0,0,0,0,0,0 To compile your program, enter the following command: icc /C+ /DMPTN /DSO32 /DOS2 myprog  For a dynamically linked, single-threaded program: LINK386 myprog.obj,,DDE4SBS.LIB DDE4SBM.LIB SO32DLL.LIB TCP32DLL.LIB OS2386.LIB  For a dynamically linked, multithreaded program: LINK386 myprog.obj,,DDE4MBS.LIB DDE4MBM.LIB SO32DLL.LIB TCP32DLL.LIB OS2386.LIB Notes: 1. When running an application that is built using DLL, the LIBPATH environment variable in your CONFIG.SYS file must include the MPTS\DLL directory. 2. For more information about the compile and link option, multithreaded libraries, and dynamic link libraries, see the IBM C Set/2 User's Guide. 3. You must include the MPTS library header files to ensure that proper function declaration and parameter types are used. ═══ 3. Sockets in the Internet Domain ═══ This section includes:  Protocols Used in the Internet Domain  Getting Started with Sockets in the Internet Domain  Network-Byte Order  Internet Address Formats  TCP/IP-specific Network Utility Routines ═══ 3.1. Protocols Used in the Internet Domain ═══ This section describes the network protocols in TCP/IP. Only the internet domain is supported by the TCP/IP protocol suite. Networking protocols such as TCP/IP are layered as shown in The Internet Layered Architecture. For more information on the internet domain and the TCP/IP protocol suite, refer to TCP/IP Illustrated, Volume 1: The Protocols. The Internet Layered Architecture ═══ 3.1.1. Transmission Control Protocol ═══ Transmission Control Protocol (TCP) is a transport protocol that provides a reliable mechanism for delivering packets between hosts on an internet network. TCP takes a stream of data, breaks it into datagrams, sends each one individually using IP, and reassembles the datagrams at the destination node. If any datagrams are lost or damaged during transmission, TCP detects this and resends the missing datagrams. The received data stream is a reliable copy of the transmitted data stream. You can use TCP sockets for both passive (server) and active (client) applications. Some calls are necessary for both types; others are role-specific. TCP is the default protocol for stream sockets in the internet domain. TCP is a connection-oriented protocol. It is used to communicate between pairs of applications. After a connection is made, it exists until the socket is closed. During the connection, data is either delivered or an error code is returned by Network Services. ═══ 3.1.2. User Datagram Protocol ═══ User Datagram Protocol (UDP) is a transport-layer datagram protocol that sends and receives whole packets across the network. UDP does not offer a guarantee of datagram delivery or duplication protection. UDP provides checksums for both the header and data portions of a datagram. However, applications that require reliable delivery of streams of data should use TCP. UDP is the default protocol for datagram sockets in the internet domain. Unlike applications using TCP, UDP applications are usually connectionless. A UDP socket application can become connected by calling the connect() API. An unconnected socket can be used to communicate with many hosts; but a connected socket, because it has a dedicated destination, can send data to, and receive data from, only one host at a time. UDP is considered an unreliable protocol because it sends its data over the network without verification. Consequently, after a packet has been accepted by the UDP interface, the arrival of the packet and the arrival order of the packet at the destination cannot be guaranteed. ═══ 3.1.3. Internet Protocol ═══ The Internet Protocol (IP) network layer provides the interface from the transport layer (host-to-host) protocols to the link-level protocols. IP is the basic transport mechanism for routing IP packets to the next gateway, router, or destination host. IP transmits packets of data from sources to destinations. Sources and destinations are hosts identified by 32-bit IP addresses, which are assigned independent of the underlying physical network. Outgoing packets automatically have an IP header prefixed to them, and incoming packets have their IP header removed before being sent to the higher-level protocols. This protocol provides for the unique addressing of hosts in an internet network. IP does not ensure a reliable communication, because it does not require acknowledgments from the sending host, the receiving host, or intermediate hosts. IP does not provide error control for data; it provides only a header checksum. IP treats each packet as an independent entity unrelated to any other packet. IP does not perform retransmissions or flow control. A higher-level protocol, TCP/IP for example, that uses IP must implement its own reliability procedures. Applications do not typically access IP directly, but rather use TCP or UDP which, in turn, use IP. Raw sockets can use IP. ═══ 3.1.4. Internet Control Message Protocol ═══ Internet Control Message Protocol (ICMP) is used to pass control information between hosts. For example, the information can be sent when a:  Host checks to see if another host is available (PING).  Packet cannot reach its destination.  Gateway or router can direct a host to send traffic on a shorter route.  Gateway or router does not have the buffering capacity to forward a packet. ICMP provides feedback about problems in the communication environment; it does not make IP reliable. The use of ICMP does not guarantee that an IP packet is delivered reliably or that an ICMP message is returned to the source host when an IP packet is not delivered or is incorrectly delivered. Raw sockets can use ICMP and similar to IP, ICMP is not typically used by application programs directly. ═══ 3.1.5. Internet Group Management Protocol ═══ Internet Group Management Protocol (IGMP) is used to communicate group membership information to hosts and routers on the network. When a host joins a multicast group, it sends an IGMP message announcing the host membership to the all-hosts multicast address (224.0.0.1). Because hosts do not send out messages when they leave a group, the gateways must periodically poll the hosts on the local network. The hosts send a membership report in response to the poll. ═══ 3.1.6. Address Resolution Protocol ═══ Address Resolution Protocol (ARP) maps IP addresses to hardware addresses. TCP/IP uses ARP to collect and distribute the information for mapping tables. ARP is not directly available to users or applications. When an application sends an internet packet, IP requests the appropriate address mapping. If the mapping is not in the mapping table, an ARP broadcast packet is sent to all the hosts on the local network requesting the physical hardware address for the host. ═══ 3.2. Getting Started with Sockets in the Internet Domain ═══ This section provides some basic information for getting started with sockets in the internet domain:  Use the socket() call to create a socket in the internet domain specifying PF_INET for the domain parameter.  Use AF_INET for the address family.  The following socket types are supported for the internet domain: - Datagram (SOCK_DGRAM) - Raw (SOCK_RAW) - Stream (SOCK_STREAM) The socket type is passed as a parameter to the socket() call. For additional information, refer to Socket Types and general socket programming concepts in Programming with Sockets.  Datagram sockets use the UDP protocol, stream sockets use the TCP protocol, and raw sockets can use the raw, ICMP, or IGMP protocols.  Use the network utility routines to get addresses with a given name (refer to TCP/IP-specific Network Utility Routines for additional information.) ═══ 3.3. Network-Byte Order ═══ Ports and addresses are specified to socket API calls by using the network-byte ordering convention. Network-byte order is also known as big endian byte ordering which has the high-order byte at the starting address. By contrast, little endian has the low-order byte at the starting address. Using network-byte ordering for data exchanged between hosts allows hosts using different underlying byte ordering conventions to exchange address information. There is a set of network utility API calls for translating addresses from host-byte to network-byte order and from network-byte to host-byte order. For more information about network-byte order and address translation, see:  bind()  htonl()  htons()  ntohl()  ntohs() Note: The socket interface does not handle application data byte ordering differences. Application writers must handle data buffer byte order differences themselves. ═══ 3.4. Internet Address Formats ═══ This section describes the address formats used in the internet domain. ═══ 3.4.1. Internet Addressing ═══ Internet protocol (IP) addresses are 32-bit values that represent a network interface. Every internet address within an administered internet (AF_INET) communication domain must be unique. A host can have as many internet addresses as it has network interfaces. For more information about internet address formats, see Internetworking with TCP/IP Volume I: Principles, Protocols, and Architectures, and Volume II: Implementation and Internals. Each internet host is assigned at least one unique internet address. This address is used by IP and other higher-level protocols. When a host is a gateway, it has more than one IP address. Gateway hosts connect two or more physical networks and have one IP address per connected physical network. An internet address can be broken down into two pieces:  The network number This identifies the physical network the address is associated with.  The host ID (or local address) This identifies a specific host on that network. All hosts on a single physical network have the same network number and can communicate with each other directly, without going through intermediate routers. Hosts on disjoint physical networks have different network numbers and must communicate through intermediate gateway hosts. Dotted-Decimal Notation: A commonly used notation for internet host addresses is the dotted-decimal notation, which divides the 32-bit address into four 8-bit fields. The value of each field is specified as a decimal number, and the fields are separated by periods (for example, 10.2.0.52). Address examples in this book use dotted-decimal notation in the following forms:  nnn.lll.lll.lll  nnn.nnn.lll.lll  nnn.nnn.nnn.lll where: nnn represents part or all of a network number. lll represents part or all of a local address. Addressing within an Internet Domain: A socket address in an internet communication domain is comprised of the five fields in the following sockaddr_in structure: length, address family, port, an internet address, and a reserved field. The sockaddr_in structure should be cleared before use. The structure is located in the header file: struct in_addr { u_long s_addr; }; struct sockaddr_in { u_char sin_family; /* AF_INET */ u_short sin_port; /* port id */ struct in_addr sin_addr; /* address */ char sin_zero[8]; /* not used */ }; The sin_family field is AF_INET. The sin_port field is the port number in network-byte order. On a bind () call, you can set this field to 0 and Network Services chooses a port for the socket. On a connect() call, you must set sin_port to the port you want to connect to. For more information on ports, see Ports. The sin_addr field is the internet address represented in network-byte order. When specified as a parameter to bind(), sin_addr is usually set to the constant INADDR_ANY, as defined in the file. This binds the socket to any and all local internet addresses. By using INADDR_ANY, an application can bind a socket without specifying the local internet address. The constant INADDR_ANY also allows an application running on a host with multiple interfaces (multihomed host) to receive UDP datagrams and TCP connection requests arriving at any interface on a single socket. (The application is not required to have one socket per interface, with each interface bound to a specific internet address). If you do not set sin_addr to INADDR_ANY, you must set it to a valid internet address for the workstation where the application is running. The sin_zero field is not used, and it should be set to 0 by the application before passing the address structure to any sockets call. ═══ 3.5. TCP/IP-specific Network Utility Routines ═══ The TCP/IP protocol provides a library, TCP32DLL, that can be used in addition to the protocol-independent SO32DLL library. This API provides a set of network utility routines to perform useful tasks such as internet address translation, domain name resolution, network-byte order translation, and access to the database of useful network information. This library can be used for the PF_INET protocol family only. Network utility routines are described in the following sections. ═══ 3.5.1. Host Names Information ═══ The following calls are host-related:  gethostbyname()  gethostbyaddr()  sethostent()  gethostent()  endhostent()  gethostname() The gethostbyname() call takes an internet host name and returns a hostent structure, which contains the name of the host, aliases, host address family and host address. The hostent structure is defined in the header file. The gethostbyaddr() call maps the internet host address into a hostent structure. The database for these calls is provided by the name server or the ETC\HOSTS file if a name server is not present or is unable to resolve the host name. The sethostent(), gethostent(), and endhostent() calls open, provide sequential access to, and close the ETC\HOSTS file. The gethostname() call gets the name for the local host machine. ═══ 3.5.2. Network Names Information ═══ The following calls are network-related:  getnetbyname()  getnetbyaddr()  setnetent()  getnetent()  endnetent() The getnetbyname() call takes a network name and returns a netent structure, which contains the name of the network, aliases, network address family, and network number. The netent structure is defined in the header file. The getnetbyaddr() call maps the network number into a netent structure. The database for these calls is provided by the ETC\NETWORKS file. The setnetent(), getnetent(), and endnetent() calls open, provide sequential access to, and close the ETC\NETWORKS file. ═══ 3.5.3. Protocol Names Information ═══ The following calls are protocol-related:  getprotobyname()  getprotobynumber()  setprotoent()  getprotoent()  endprotoent() The getprotobyname() call takes the protocol name and returns a protoent structure, which contains the name of the protocol, aliases, and protocol number. The protoent structure is defined in the header file. The getprotobynumber() call maps the protocol number into a protoent structure. The database for these calls is provided by the ETC\PROTOCOL file. The setprotoent(), getprotoent(), and endprotoent() calls open, provide sequential access to, and close the ETC\PROTOCOL file. ═══ 3.5.4. Service Names Information ═══ The following calls are service-related:  getservbyname()  getservbyport()  setservent()  getservent()  endservent() The getservbyname() call takes the service name and protocol, and returns a servent structure that contains the name of the service, aliases, port number, and protocol. The servent structure is defined in the header file. The getservbyport() call maps the port number and protocol into a servent structure. The database for these calls is provided by the ETC\SERVICES file. The setservent(), getservent(), and endservent() calls provide open, provide sequential access to, and close the ETC\SERVICES file. ═══ 3.5.5. Network-Byte Order Translation ═══ Internet domain ports and addresses are usually specified to calls using the network-byte ordering convention. The following are the network-byte order translation calls:  htonl()  htons()  ntohl()  ntohs() The htonl() and htons() calls translate host-byte order to network-byte order for long integers (32-bit) and short integers (16-bit). The ntohl() and ntohs() calls translate network-byte order to host-byte order for long integers (32-bit) and short integers (16-bit). ═══ 3.5.6. Internet Address Manipulation ═══ The following calls convert internet addresses and decimal notation, and manipulate the network number and local network address portions of an internet address:  inet_addr()  inet_network()  inet_ntoa()  inet_netof()  inet_lnaof()  inet_makeaddr() The inet_addr() and inet_network() calls translate dotted-decimal notation to a 32-bit internet address (network-byte order) or to a network number (host-byte order, with zeros in the host part.) The inet_ntoa() call translates 32-bit internet address (network-byte order) to dotted-decimal notation. The inet_netof() and inet_lnaof() calls extract the network number (host-byte order) or the local network address (host-byte order) from a 32-bit internet address (network-byte order). The inet_makeaddr() call constructs internet address (network-byte order) from network number and local network address. ═══ 3.5.7. Domain Name Resolution ═══ Domain name resolution calls are used to resolve the symbolic host name into an internet address and to extract more information about the host from the database. The resolution calls determine whether the name server is present by referencing the ETC\RESOLV file. To resolve a name with no name server present, the resolution calls check the ETC\HOSTS file for an entry that maps the name to an address. To resolve a name in a name server network, the resolution calls query the domain name server database. If this query fails, the calls then check for an entry in the local ETC\HOSTS file. The following resolution calls are used to make, send, and interpret packets for name servers in the internet domain:  res_mkquery()  res_send()  res_init()  dn_comp()  dn_expand() ═══ 3.5.8. Ports ═══ A port is used to differentiate between different applications on a host using the same protocol (TCP or UDP). It is an additional qualifier used by Network Services to get data to the correct application. Physically, a port is a 16-bit integer. Some ports are reserved for particular applications and are called well-known ports. Well-Known Port Assignments contains the well-known port assignments list. ═══ 4. Sockets over Local IPC ═══ The sockets over the Local IPC domain allow the programmer to communicate between applications on the same machine using the sockets API. Local IPC sockets are not bound to a network protocol, but rather use the underlying host facilities to provide high performance IPC. This section includes:  Getting Started with Sockets Over Local IPC  Local IPC Address Format ═══ 4.1. Getting Started with Sockets Over Local IPC ═══ This section provides some basic information for getting started with sockets over Local IPC:  Use AF_OS/2 or AF_UNIX for the protocol family.  Use AF_OS/2, AF_LOCAL, or AF_UNIX for the address family.  The following socket types are supported for the Local IPC domain: - Datagram (SOCK_DGRAM) - Stream (SOCK_STREAM) The socket type is passed as a parameter to the socket() call. For additional information, refer to Socket Types and general socket programming concepts in Programming with Sockets.  A unique text string is used as a name. Refer to the discussion of sun_path in the following section for additional details.  If a connect() socket call is received without an explicit bind(), an implicit bind is automatically performed. In this case, the application does not care about its own name and a unique Local IPC name is generated by Network Services. You can retrieve the Local IPC name by using the getsockname() call. ═══ 4.2. Local IPC Address Format ═══ The Local IPC address format is comprised of the three fields in the following sockaddr_un structure: length, address family, and the path name. The structure is located in the header file: struct sockaddr_un { u_char sun_family; /* AF_OS2, AF_LOCAL, or AF_UNIX */ char sun_path[108]; /* path name */ }; The sun_family field is set to AF_OS2, AF_LOCAL, or AF_UNIX. The sun_path field is the OS/2 Warp Connect file and path name to be used as the address of the Local IPC socket. Each address is a combination of address family (sun_family) and a character string (sun_path) containing no more than 108 characters. Each socket must use a unique character string as its local name. ═══ 5. Sockets over NetBIOS ═══ This section discusses using sockets over the NetBIOS communication domain. In this domain, each application assigns itself one or more NetBIOS names for each adapter. The NetBIOS protocol maintains a table of the names that a node is known by on the network. NetBIOS supports two types of names: unique and group. When the name is unique, the application binds the name and NetBIOS checks the network to ensure that the name is not already being used as a unique name. When using group names, NetBIOS supports multicast by allowing applications to bind to a group name and communicate. This section includes:  Getting Started with Sockets Over NetBIOS  NetBIOS Address Format ═══ 5.1. Getting Started with Sockets Over NetBIOS ═══ This section provides some basic information for getting started with sockets over NetBIOS:  Use AF_NETBIOS or AF_NB for the protocol family.  Use AF_NETBIOS or AF_NB for the address family.  The following socket types are supported for the NetBIOS domain: - Datagram (SOCK_DGRAM) - Sequenced packet (SOCK_SEQPACKET) - Stream packet (SOCK_STREAM) The socket type is passed as a parameter to the socket() call. For additional information, refer to Socket Types and general socket programming concepts in Programming with Sockets.  If a connect() socket call is received without an explicit bind(), an implicit bind is automatically performed. In this case, the application does not care about its own name and a unique NetBIOS name is generated by Network Services.  Applications using the NetBIOS communication domain can use sockets in both a connection-oriented (sequenced packet) and connectionless (datagram) mode. For additional information, refer to Connection Modes.  A NetBIOS application on one workstation can use sockets to communicate with an NCB NetBIOS application on a different workstation. ═══ 5.2. NetBIOS Address Format ═══ The NetBIOS address format is comprised of the six fields in the following sockaddr_nb structure: length, address family, address type, a reserved field, adapter number, and NetBIOS name. This structure is located in the header file: struct sockaddr_nb { u_char snb_family; /* AF_NetBIOS */ short snb_type; /* 0=>unique or 1=>multicast */ char snb_nbnetid[NB_NETIDLEN]; /* NetBIOS NetID */ unsigned short snb_adapter; /* adapter number */ char snb_name[NAMELEN]; /* NetBIOS name */ } The snb_family field is set to AF_NETBIOS or AF_NB. The address type field (snb_type) is used to specify the name as either a unique (NB_UNIQUE) or a group (NB_GROUP) name. The snb_adapter field contains the adapter number that the name is associated with. The adapter number must be a numeric value in the range 0-255. The snb_name field contains the 16-byte NetBIOS name. If a connect() socket call is received without an explicit bind(), an implicit bind is automatically performed. In this case, the application does not care about its own name and is asking Network Services to select one for it. A NetBIOS name is generated for this socket by converting the 6-byte MAC address to an ASCII hexadecimal string, and is postpended with a 2-byte number that increments after each use. You can retrieve the NetBIOS name by using the getsockname() call. Note that for the NetBIOS domain, more than one socket can be bound to the same local address to establish multiple connections to one or more remote destinations. To enable this feature, the socket option SO_REUSEADDR must be set. See setsockopt(). In addition, you can bind more than one address to the same adapter. ═══ 6. Protocol-Independent C Sockets API ═══ The following table briefly describes each protocol-independent socket call supported by MPTS and identifies the location in the book where you can find the syntax, parameters, and other appropriate information. The socket calls described in this section can be used to access services for all protocols: ┌───────────────────────────────────────────────────────────────────────┐ │ Table 9. Protocol-Independent Sockets API Quick Reference │ ├──────────────┬────────────────────────────────────────────────────────┤ │ SOCKET CALL │ DESCRIPTION │ ├──────────────┼────────────────────────────────────────────────────────┤ │ accept() │ Accepts a connection request │ ├──────────────┼────────────────────────────────────────────────────────┤ │ bind() │ Binds a local name to the socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ connect() │ Requests a connection to another socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ getpeername()│ Gets the name of the peer connected to socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ getsockname()│ Gets the local socket name │ ├──────────────┼────────────────────────────────────────────────────────┤ │ getsockopt() │ Gets the socket options associated with a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ ioctl() │ Performs special operations on socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ listen() │ Completes binding so that a socket can accept con- │ │ │ nections and creates a connection request queue for │ │ │ incoming requests │ ├──────────────┼────────────────────────────────────────────────────────┤ │ psock_errno()│ Writes a short error message to the standard error │ │ │ device │ ├──────────────┼────────────────────────────────────────────────────────┤ │ readv() │ Receives data on a socket into a set of buffers │ ├──────────────┼────────────────────────────────────────────────────────┤ │ recv() │ Receives data on a connected socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ recvfrom() │ Receives data on a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ recvmsg() │ Receives data and control information on a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ select() │ Gets read, write, and exception status on a group of │ │ │ sockets │ ├──────────────┼────────────────────────────────────────────────────────┤ │ send() │ send() │ ├──────────────┼────────────────────────────────────────────────────────┤ │ sendmsg() │ Sends data and control information on a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ sendto() │ Sends data on a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ setsockopt() │ Sets options associated with a socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ shutdown() │ Shuts down all or part of a full duplex connection │ ├──────────────┼────────────────────────────────────────────────────────┤ │ sock_errno() │ Returns error code set by a socket call │ ├──────────────┼────────────────────────────────────────────────────────┤ │ socket() │ Creates an endpoint for communication and returns a │ │ │ socket descriptor │ ├──────────────┼────────────────────────────────────────────────────────┤ │ soclose() │ Shuts down a socket and frees resources allocated to │ │ │ the socket │ ├──────────────┼────────────────────────────────────────────────────────┤ │ writev() │ Writes data from a set of specified buffers on a │ │ │ socket │ └──────────────┴────────────────────────────────────────────────────────┘ Note: If you are using the internet communications domain (PF_INET protocol family), you can use all APIs in the previous table and those in section TCP/IP Network Utility Routines. All other communication domains can only use those APIs listed in the previous table. ═══ 6.1. accept() ═══ Accepts a connection request from a remote host. #include #include #include #include #include int accept(s, name, namelen) int s; struct sockaddr *name; int *namelen; Parameter Description s Socket descriptor. name Pointer to a sockaddr structure that contains the socket address of the connection client when the accept() call returns. The format of name is determined by the communications domain where the client resides. This parameter can be NULL if the caller is not interested in the client address. namelen Must initially point to an integer that contains the size in bytes of the storage pointed to by name. On return, that integer contains the size of the data returned in the storage pointed to by name. If name is NULL, namelen is ignored and can be NULL. Description: This call is used by a server acting in a connection-oriented mode to accept a connection request from a client. The call accepts the first connection on its queue of pending connection requests. The accept() call creates a new socket descriptor with the same properties as s and returns it to the caller. The new socket descriptor cannot be used to accept new connections. The original socket, s, remains available to accept more connection requests. If the queue has no pending connection requests, accept() blocks the caller unless s is in nonblocking mode. If no connection requests are queued and s is in nonblocking mode, accept() returns -1 and sets the return code to SOCEWOULDBLOCK. The s parameter must be a socket descriptor created with the socket() call. It is usually bound to an address with the bind() call and must be made capable of accepting connections with the listen() call. The listen() call marks the socket as one that accepts connections and allocates a queue to hold pending connection requests. The listen() call allows the caller to place an upper boundary on the size of the queue. The name parameter is a pointer to a sockaddr structure where the connection requester address is placed. The name parameter is optional and can be set to be the NULL pointer. If set to NULL, the requester address is not copied into the sockaddr structure. The exact format of name depends on the communications domain where the communication request originated. For example, if the connection request originated in the internet domain, name points to a sockaddr_in structure as defined in the header file . The namelen parameter is used only if name is not NULL. Before calling accept(), you must set the integer pointed to by namelen to the size, in bytes, of the sockaddr structure pointed to by name. On successful return, the integer pointed to by namelen contains the actual number of bytes copied into the sockaddr structure. If the sockaddr structure is not large enough to hold the address, up to namelen bytes of the requester address are copied. This call is used only with SOCK_STREAM or SOCK_SEQPACKET sockets. You cannot screen requesters without calling accept(). The application cannot tell the Network Services software which requesters to accept connections from. The caller can, however, choose to close a connection immediately after discovering the identity of the requester. The select() call can be used to check the socket for incoming connection requests. Return and sock_errno() Values: A non-negative socket descriptor indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using name and namelen results in an attempt to copy the address into a portion of the caller address space where information cannot be written. SOCEINVAL Listen() was not called for socket s. SOCENOBUFS Insufficient buffer space is available to create the new socket. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEOPNOTSUPP The s parameter is not connection-oriented. SOCEWOULDBLOCK The s parameter is in nonblocking mode and no connections are on the queue. Examples: The following are two examples of the accept() call. In the first, the caller wants to have the requester address returned. In the second, the caller does not want to have the requester address returned. int clientsocket; int s; struct sockaddr clientaddress; int addrlen; int accept(int s, struct sockaddr *addr, int *addrlen); /* extracted from sys\socket.h */ /* socket(), bind(), and listen() have been called */ /* EXAMPLE 1: I want the address now */ addrlen = sizeof(clientaddress); clientsocket = accept(s, &clientaddress, &addrlen); /* EXAMPLE 2: I can get the address later using getpeername() */ clientsocket = accept(s, (struct sockaddr *) 0, (int *) 0); ═══ 6.2. bind() ═══ Binds a local name to the socket. #include #include int bind(s, name, namelen) int s; struct sockaddr *name; int namelen; Parameter Description s Socket descriptor returned by a previous call to socket(). name Pointer to a sockaddr structure containing the name that is to be bound to s. namelen Size in bytes of the sockaddr structure pointed to by name. Description: This call binds a unique local name to the socket with descriptor s. After calling socket(), a descriptor does not have a name associated with it. However, it does belong to a particular protocol family as specified when socket() is called. The exact format of a name depends on the protocol family. The bind() procedure also allows servers to specify the network interfaces the program wants to receive data from. The format of name is determined by the domain where communication occurs. If the caller is not interested in its own address, set the protocol-dependent fields within the sockaddr structure to NULL and Network Services assigns an address for it. This enables data to be received from any address, sometimes referred to as wildcard addressing. Data cannot be received from any address using raw sockets. In the internet domain, set sin_port in the sockaddr_in structure to a specific port or to 0, which indicates that Network Services should select Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCEADDRINUSE The address is already in use. See the SO_REUSEADDR option described under getsockopt() and the SO_REUSEADDR option described under setsockopt(). SOCEADDRNOTAVAIL The address specified is not valid on this host. For example, the internet address does not specify a valid network interface. SOCEAFNOSUPPORT The address family is not supported. SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using name and namelen results in an attempt to read from a non-readable portion of the application address space. SOCEINVAL The socket is already bound to an address, or namelen is not the expected length. SOCENOBUFS No buffer space is available. SOCENOTSOCK The s parameter is not a valid socket descriptor. Examples: Note the following about the bind() call examples:  For the internet examples, put the internet address and port in network-byte order. To put the port into network-byte order, use the htons() utility routine to convert a short integer from host-byte order to network-byte order.  For the internet examples, set the address field using the inet_addr() utility routine, which takes a character string representing the dotted-decimal address of an interface and returns the binary internet address representation in network-byte order.  Zero the structure before using it to ensure that the name requested does not set any reserved fields. See connect() for examples of how a client can connect to servers. int rc; int s; struct sockaddr_in myname; int bind(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ /* Bind to a specific interface in the internet domain */ /* clear the structure */ memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_addr = inet_addr("129.5.24.1"); /* specific interface */ myname.sin_port = htons(1024); . . . rc = bind(s, (struct sockaddr *) &myname, sizeof(myname)); /* Bind to all internet network interfaces on the system */ /* clear the structure */ memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_addr.s_addr = INADDR_ANY; /* all interfaces */ myname.sin_port = htons(1024); . . . rc = bind(s, (struct sockaddr *) &myname, sizeof(myname)); /* Bind to a specific interface in the internet domain. Let Network Services choose a port */ /* clear the structure */ memset(&myname, 0, sizeof(myname)); myname.sin_family = AF_INET; myname.sin_addr = inet_addr("129.5.24.1"); /* specific interface */ myname.sin_port = 0; . . . rc = bind(s, (struct sockaddr *) &myname, sizeof(myname)); /* Bind to a unique NetBIOS name on adapter 0 */ struct sockaddr_nb nbname; memset(&nbname, 0, sizeof(nbname)); nbname.snb_family = AF_NB; nbname.snb_type = NB_UNIQUE; nbname.snb.netid[b]=0; nbname.snb_adapter = 0; strcpy(nbname.snb_name, "NBSERVER"); /* Note that a NetBIOS name is 16 bytes long. In this example, the last 8 bytes are filled with zeros. */ . . . rc = bind(s, (struct sockaddr *) &nbname, sizeof(nbname)); ═══ 6.3. connect() ═══ Requests a connection to another socket. #include #include int connect(s, name, namelen) int s; struct sockaddr *name; int namelen; Parameter Description s Socket descriptor used to originate the connection request. name Pointer to a sockaddr structure containing the address of the socket to which a connection is attempted. namelen Size in bytes of the sockaddr structure pointed to by name. Description: Stream or sequenced packet sockets: The connect() call performs two tasks when called for a stream or sequenced packet socket: 1) it completes the binding if necessary for a socket, and 2) it attempts to create a connection between two sockets. This call is used by the client side of socket-based applications to establish a connection with a server. The server must have a passive open pending. This means the server must successfully call bind() and listen(). Otherwise, connect() returns -1 and the error value is set to SOCECONNREFUSED. In the internet communication domain, a timeout occurs if a connection to the remote host is not successful within 75 seconds (1 minute and 15 seconds). There is no timeout for Local IPC. In the NetBIOS communication domain, a timeout occurs if a connection to the host is not successful within the time defined by the NetBIOS protocol parameters Transmit Timer multiplied by Transmit Retry. If s is in blocking mode, the connect() call blocks the caller until the connection is established or until an error is received. If the socket is in nonblocking mode and the connection was successfully initiated, connect() returns -1 and sets the error value to SOCEINPROGRESS. The caller can test the completion of the connection setup by calling: 1) select() to test for the ability to write to the socket, and 2) getsockopt() with option SO_ERROR to test if the connection succeeded. Stream or sequenced packet sockets can call connect() only once. Even if the connection attempt fails, you must use soclose() to close the socket and use socket() to create a new socket before trying to connect again. Datagram or raw sockets: The connect() call specifies the destination peer address when called for a datagram or raw socket. Normally, datagram and raw sockets use connectionless data transfer calls such as sendto() and recvfrom(). However, applications can call connect() to specify and store the destination peer address for this socket. This identifies which address to send data to on this socket. This method of communication allows datagram and raw sockets to be connected. However, data is still not guaranteed to be delivered. Thus, the normal characteristics of connectionless mode sockets is maintained. The address is remembered until another connect() call is made. This permits the use of readv(), recv(), send(), and writev(), which are usually reserved for connection-oriented sockets. The application can still use sendto(), recvfrom(), sendmsg(), and recvmsg(). The advantage of calling connect() and being connected is that the destination peer address does not have to be specified for all datagrams sent. Also, when a datagram socket is connected, only datagrams from the connected peer are delivered to the socket. Datagram and raw sockets can call connect() multiple times. The application can reset their destination address by specifying a new address on the connect() call. In addition, the socket can be returned to operate in a connectionless mode by calling connect() with a null destination address. The null address is created by zeroing the sockaddr structure and setting only the address family field. The call to connect returns -1, indicating that the connection to the null address cannot be established. Calling sock_errno() returns SOCEADDRNOTAVAIL. For more information on connecting datagram sockets, see "Description" for sendto(). Examples: Note the following about these connect() call examples:  For the internet examples, put the internet address and port in network-byte order. To put the port into network-byte order, use the htons() utility routine to convert a short integer from host-byte order to network-byte order.  For the internet examples, set the address field using the inet_addr() utility routine, which takes a character string representing the dotted-decimal address of an interface and returns the binary internet address representation in network-byte order.  To ensure that the name requested does not set any reserved fields, zero the structure before using it . These examples could be used to connect to the servers shown in the examples listed for bind(). int s; struct sockaddr_in servername; int rc; int connect(int s, struct sockaddr *name, int namelen); /* extracted from sys\socket.h */ /* Connect to server bound to a specific interface in the internet domain */ /* clear the structure */ memset(&servername, 0, sizeof(servername)); servername.sin_family = AF_INET; servername.sin_addr.s_addr = inet_addr("129.5.24.1"); /* specific interface */ servername.sin_port = htons(1024); /* set to the port to which */ /* the server is bound */ . . . rc = connect(s, (struct sockaddr *) &servername, sizeof(servername)); /* Connect to a NetBIOS server */ struct sockaddr_nb nbservername; memset(&nbservername, 0, sizeof(nbservername)); nbservername.snb_family = AF_NB; nbservername.snb_type = NB_UNIQUE; nbname.snb_nbnetID[0]v= "0"; strcpy(nbservername.snb_name, "NBSERVER"); . . . rc = connect(s, (struct sockaddr *) &nbservername, sizeof(nbservername)); Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCEADDRNOTAVAIL The calling host attempted to connect to port 0, or no local address exists for the connecting socket to be implicitly bound to at the time of the connect. SOCEAFNOSUPPORT The address family is not supported. SOCEALREADY The socket s is marked nonblocking, and a previous connection attempt has not completed. SOCECOMMSYS Internal communications error. Contact IBM Service. SOCECONNREFUSED The connection request was rejected by the destination host. This error code implies that the connection request was received at the destination host but a socket bound to the destination port does not exist. SOCEFAULT Using name and namelen results in an attempt to read from a non-readable portion of the application address space. SOCEINPROGRESS The socket s is marked nonblocking, and the connection cannot be completed immediately. The SOCEINPROGRESS value does not indicate an error condition. SOCEINVAL The namelen parameter is not a valid length. For a stream socket, a previous connection was refused or received SOCEALREADY and then failed. SOCEISCONN The socket s is already connected. SOCENETUNREACH The network cannot be reached from this host. SOCENOBUFS No buffer space is available. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCETIMEDOUT The connection establishment timed out before a connection was made. This error code usually implies that the connection request is not reaching the destination (or the destination's reply is not reaching the requester). This error is also returned if the connection request does reach the destination, and a socket is bound to the specified destination port, but listen() has not been issued for that socket. ═══ 6.4. getpeername() ═══ Gets the name of the peer connected to socket. #include #include int getpeername(s, name, namelen) int s; struct sockaddr *name; int *namelen; Parameter Description s Socket descriptor. name Pointer to a sockaddr structure. The name of the peer connected to socket s is returned. The exact format of name is determined by the domain where communication occurs. namelen Pointer to the size in bytes of the sockaddr structure pointed to by name. Description: This call returns the name of the peer connected to socket s. The namelen parameter must be initialized to indicate the size of the space pointed to by name. On return, namelen is set to the size of the peer name copied. If the sockaddr structure is too small, the peer name is truncated. This call operates only on connected sockets. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using the name and namelen parameters as specified results in an attempt to access storage outside of the address space of the caller. SOCENOBUFS No buffer space is available. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. ═══ 6.5. getsockname() ═══ Gets the local socket name. #include #include int getsockname(s, name, namelen) int s; struct sockaddr *name; int *namelen; Parameter Description s Socket descriptor. name Pointer to a sockaddr structure. The name of s is returned. namelen Pointer to the size in bytes of the sockaddr structure pointed to by name. Description: This call returns the name for the socket specified by the s parameter in the structure pointed to by the name parameter. It returns the address to the socket that has been bound. If the socket is not bound to an address, the call returns with the family set and the rest of the structure is set to zero. For example, an unbound socket in the internet domain causes the name to point to a sockaddr_in structure with the sin_family field set to AF_INET and all other fields zeroed. The namelen parameter must be initialized to indicate the size of the space pointed to by name and is set to the size of the local name copied. If the sockaddr structure is too small, the local name is truncated. Sockets are explicitly assigned a name after a successful call to bind(). Stream and sequenced packet sockets are implicitly assigned a name after a successful call to connect() or accept() if bind() was not called. The getsockname() call is often used to discover the port assigned to a socket after the socket has been implicitly bound to a port. For example, an application can call connect() without previously calling bind(). In this case, the connect() call completes the binding necessary by assigning a port to the socket. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using the name and namelen parameters as specified results in an attempt to access storage outside of the address space of the caller. SOCEINVAL The socket received an error, such as a timed out connect. SOCENOBUFS No buffer space is available. SOCENOTSOCK The s parameter is not a valid socket descriptor. ═══ 6.6. getsockopt() ═══ Gets the socket options associated with a socket. #include #include int getsockopt(s, level, optname, optval, optlen) int s; int level; int optname; char *optval; int *optlen; Parameter Description s Socket descriptor. level Specifies which option level is being queried for the specified optname. optname Name of a specified socket option. Only one option can be specified on a call. optval Pointer to buffer to receive the option data requested. optlen Pointer to the size of the buffer. Description: This call returns the value of a socket option at the socket or protocol level. It can be called for sockets of all domain types. Some options are supported only for specific socket types. You must specify the level of the option and the name of the option to retrieve option values. The following table lists the supported levels. ┌─────────────────────────────────────────────────┐ │ Table 10. Supported Levels │ ├──────────────────────┬──────────────────────────┤ │ SUPPORTED LEVEL │ #DEFINE IN │ ├──────────────────────┼──────────────────────────┤ │ SOL_SOCKET │ │ ├──────────────────────┼──────────────────────────┤ │ IPPROTO_IP │ │ ├──────────────────────┼──────────────────────────┤ │ IPPROTO_TCP │ │ ├──────────────────────┼──────────────────────────┤ │ NBPROTO_NB │ │ └──────────────────────┴──────────────────────────┘ The optval parameter is a pointer to the buffer where the option values are returned. The optlen parameter must be initially set to the size of the buffer before calling getsockopt(). On return, the optlen parameter is set to the actual size of the data returned. For socket options that are boolean, the option is enabled if optval is nonzero and disabled if optval is 0. The following tables list the supported options for getsockopt() at each level (SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP, NBPROTO_NB). Detailed descriptions of the options follow each table. ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 11. Supported getsockopt() Socket Options for SOL_SOCKET │ ├─────────────────┬────────────────────────────┬──────────┬────────┬──────────┤ │ │ │ DOMAINS │ DATA │ BOOLEAN │ │ OPTION NAME │ DESCRIPTION │ * │ TYPE │ OR VALUE │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_BROADCAST │ allows sending of broad- │ I, N │ int │ boolean │ │ │ cast messages │ │ │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_DEBUG │ turns on recording of │ I, L │ int │ boolean │ │ │ debugging information │ │ │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_DONTROUTE │ bypasses routing tables │ I, L │ int │ boolean │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_ERROR │ gets any pending error and │ I, L │ int │ value │ │ │ clear │ │ │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_KEEPALIVE │ keeps connections alive │ I │ int │ boolean │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_LINGER │ lingers on close if data │ I │ struct │ value │ │ │ present │ │ linger │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_OOBINLINE │ leaves received OOB data │ I │ int │ boolean │ │ │ in-line │ │ │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVBUF │ receives buffer size │ I, L, N │ long │ value │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVLOWAT │ receives low-water mark │ I, L │ int │ value │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVTIMEO │ receives timeout │ I, L, N │ struct │ value │ │ │ │ │ timeval│ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_REUSEADDR │ allows local address reuse │ I, N │ int │ boolean │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_REUSEPORT │ allows socket to reuse a │ I │ int │ boolean │ │ │ local address and local │ │ │ │ │ │ port │ │ │ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDBUF │ sends buffer size │ I, L, N │ long │ value │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDLOWAT │ sends low-water mark │ I, L │ int │ value │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDTIMEO │ sends timeout │ I, L, N │ struct │ value │ │ │ │ │ timeval│ │ ├─────────────────┼────────────────────────────┼──────────┼────────┼──────────┤ │ SO_TYPE │ gets socket type │ I, L, N │ int │ value │ ├─────────────────┴────────────────────────────┴──────────┴────────┴──────────┤ │ NOTE: * This column specifies I for internet, L for Local IPC, and N for │ │ NetBIOS communication domains. │ └─────────────────────────────────────────────────────────────────────────────┘ The following options are recognized for option level SOL_SOCKET: Option Description SO_BROADCAST (datagram sockets only) Retrieves the current ability of the socket to broadcast messages. If this option is enabled, it allows the application to send broadcast messages over s, if the interface specified in the destination supports broadcasting of packets. SO_DEBUG Retrieves the current ability for recording debug information for a socket. SO_DONTROUTE Retrieves the current ability for the socket to bypass routing. When this option is enabled, it causes outgoing messages to bypass the standard routing algorithm and be directed to the appropriate network interface, according to the network portion of the destination address. When enabled, packets can be sent to directly connected networks (networks this host has an interface for) only. SO_ERROR Returns any pending error on the socket and clears the error status. It can be used to check for asynchronous errors on connected datagram sockets or for other asynchronous errors (errors that are not returned explicitly by one of the socket calls). SO_KEEPALIVE (stream sockets only) Retrieves the current ability of the socket to send keepalive packets. TCP uses a timer called the keepalive timer. This timer is used to monitor idle connections that may have been disconnected because of a peer crash or timeout. If this option is set to ON, a keepalive packet is periodically sent to the peer. This is mainly used to allow servers to close connections that are no longer active as a result of clients going away without properly closing connections. SO_LINGER (stream sockets only) Retrieves the current ability of the socket to linger on close. When this option is enabled, and data is present in the socket's send buffer when soclose() is called, the calling application is blocked in soclose() until the data is transmitted or until the linger timeout expires. If the linger timeout expires, the unsent data is discarded, the connection is reset, and soclose() returns -1 with an error value of SOCEWOULDBLOCK. Even though soclose() returned an error, the socket is closed (no further calls can be made for the socket). Note that a linger timeout of zero results in no lingering if unsent data exists. A timeout of zero expires immediately when the call is issued, resulting in discarding any unsent data and resetting the connection. When this option is disabled (the default), soclose() does not block when unsent data is present at the time of the call. Rather, the soclose() completes immediately and TCP continues to attempt to send the remaining data before closing the connection. The application has no guarantee that the data is sent, because errors encountered on the connection after the socket is closed cannot be reported to the application. SO_OOBINLINE (stream sockets only) Retrieves the current ability of the socket to receive out-of-band data. When this option is enabled, it causes out-of-band data to be placed in the normal data input queue as it is received, making it available to recv(), and recvfrom() without having to specify the MSG_OOB flag in those calls. When this option is disabled, it causes out-of-band data to be placed in the priority data input queue as it is received, making it available to recv(), and recvfrom(), only by specifying the MSG_OOB flag in those calls. SO_RCVBUF Retrieves buffer size for input. This value tailors the receive buffer size for specific application needs, such as increasing the buffer size for high-volume connections. SO_RCVLOWAT Retrieves receive low-water mark that controls when a recv() call returns when less data is available than the recv() call is requesting. If at least SO_RCVLOWAT bytes are available, then the recv() call returns those bytes. The default is 1 for both stream and datagram sockets. SO_RCVTIMEO Retrieves receive timeout information. This value limits the length of a blocking receive call. This value is ignored for non-blocking calls. SO_REUSEADDR (stream and datagram sockets only) Retrieves the current ability of the socket to reuse local addresses. When enabled, this option allows local addresses that are already in use to be bound. This alters the normal algorithm used in the bind() call. At connect time, Network Services checks to be sure that no local address and port have the same foreign address and port. The error SOCEADDRINUSE is returned if the association already exists. SO_REUSEPORT Retrieves the current ability of the socket to reuse a local address and local port. SO_SNDBUF Retrieves the size of the send buffer. This value tailors the send buffer size for specific application needs, such as increasing the buffer size for high-volume connections. SO_SNDLOWAT Retrieves send low-water mark that influences socket flow control operations. SO_SNDLOWAT is used for stream sockets, but not datagram sockets. During a send operation, if the socket code must wait for space to be available in the send buffer before sending data, the socket waits for at least SO_SNDLOWAT bytes to be available in the send buffer before sending the data. The default value is the size of a cluster mbuf. SO_SNDTIMEO Retrieves send timeout information. This value limits the length of a blocking send call. This value is ignored for non-blocking calls. SO_TYPE Returns the type of the socket. On return, the integer pointed to by optval is set to one of the following: SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM, or SOCK_RAW. struct linger: For the SO_LINGER option, optval points to a linger structure. This structure is defined in the file and contains the following fields: Field Description l_onoff Option on/off l_linger Linger time The l_onoff field is set to zero if the SO_LINGER option is being disabled. A nonzero value enables the option. The l_linger field specifies the amount of time in seconds to linger on close. A value of zero causes an abnormal close. TCP discards any data still queued to be sent on the connection and sends a reset to the peer. The peer sees this as an abnormal close when it gets an error on an outstanding receive. struct timeval: For the SO_RCVTIMEO and SO_SNDTIMEO options, optval points to a timeval structure. This structure is defined in the file and contains the following fields: Field Description tv_sec Number of seconds tv_usec Number of microseconds For the internet domain, the finest resolution is milliseconds, thus the tv_usec field is converted. In this conversion, anything less than a millisecond is truncated. For example, if you call setsockopt() to set tv_usec to 31, the next getsockopt() call returns a 0 for tv_usec. If you call setsockopt() to set tv_usec to 1031, the next getsockopt() returns 1000. ┌────────────────────────────────────────────────────────────────────────┐ │ Table 12. Supported getsockopt() Socket Options for IPPROTO_IP │ ├──────────────────────┬────────────────────────────────┬───────┬────────┤ │ │ │ │ BOOLEAN│ │ │ │ DATA │ OR │ │ OPTION NAME │ DESCRIPTION │ TYPE │ VALUE │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_MULTICAST_IF │ provides the default interface │ struct│ value │ │ │ for outgoing multicasts │ in_add│ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_MULTICAST_LOOP │ causes a loopback of outgoing │ uchar │ boolean│ │ │ multicast │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_MULTICAST_TTL │ provides default TTL for out- │ uchar │ value │ │ │ going multicast │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_OPTIONS │ provides options in IP header │ void │ value │ │ │ to be included in outgoing │ * │ │ │ │ datagrams │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_RECVDSTADDR │ allows queueing of IP destina- │ int │ boolean│ │ │ tion address │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_TOS │ gives type of service for out- │ int │ boolean│ │ │ going datagrams │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ IP_TTL │ gives time to live for out- │ int │ value │ │ │ going datagrams │ │ │ └──────────────────────┴────────────────────────────────┴───────┴────────┘ The following options are recognized for option level IPPROTO_IP and are supported for the internet communication domain only. Option Description IP_MULTICAST_IF Retrieves the default interface for outgoing multicasts. Normally this is the interface selected for an outgoing interface based on the destination. This default can be overridden by specifying the IP address of the outgoing interface. IP_MULTICAST_LOOP Retrieves the value of the loopback setting for outgoing multicasts. If this value is 0, packets are not looped back and delivered to the transmitting interface, even if the interface is a member of the multicasting group. If this value is 1, packets are looped back if the interface is a member of the multicasting group. The default value is 1. IP_MULTICAST_TTL Retrieves the default TTL for outgoing multicasts. The default is 1, which causes multicast datagrams to remain on the local network. This value is also used by multicast routers to have a threshold policy to drop multicast packets. Packets can be dropped by a router even though its TTL is not 0. IP_OPTIONS Retrieves the options in the IP header that are included in outgoing datagrams. IP_RECVDSTADDR (datagram sockets only) Retrieves if IP destination address is passed on the recvmsg() call is enabled or disabled. The IP destination is passed pack in the msg_control parameter, if the msg_controllen parameter is less than 4 bytes, the flags indicate the control information was truncated. IP_TOS Retrieves the type of service (TOS) used in outgoing datagram and stream packets. IP_TTL Retrieves the time to live (TTL) for outgoing unicast packets. A TTL value of 1 prevents packets from being routed to other networks. Raw sockets default to the maximum of 255, datagram and stream sockets default to 64. ┌────────────────────────────────────────────────────────────────────────┐ │ Table 13. Supported getsockopt() Socket Options for IPPROTO_TCP │ ├──────────────────────┬────────────────────────────────┬───────┬────────┤ │ │ │ │ BOOLEAN│ │ │ │ DATA │ OR │ │ OPTION NAME │ DESCRIPTION │ TYPE │ VALUE │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ TCP_MAXSEG │ gets TCP maximum segment size │ int │ value │ │ │ after a connection is estab- │ │ │ │ │ lished │ │ │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ TCP_NODELAY │ indicates that the send to │ int │ boolean│ │ │ coalesce packets should not be │ │ │ │ │ delayed │ │ │ └──────────────────────┴────────────────────────────────┴───────┴────────┘ The following options are recognized for option level IPPROTO_TCP and are supported for the internet communication domain only. Option Description TCP_MAXSEG Retrieves the TCP maximum segment size after a connection is established. TCP_NODELAY (stream sockets only) Retrieves the current ability of the socket to disable the small packet avoidance algorithm so that the client's TCP sends small packets as soon as possible. This option may provide a performance improvement for some applications on a LAN, but can degrade performance on Wide Area Networks (WAN). ┌────────────────────────────────────────────────────────────────────────┐ │ Table 14. Supported getsockopt() Socket Options for NBPROTO_NB │ ├──────────────────────┬────────────────────────────────┬───────┬────────┤ │ │ │ │ BOOLEAN│ │ │ │ DATA │ OR │ │ OPTION NAME │ DESCRIPTION │ TYPE │ VALUE │ ├──────────────────────┼────────────────────────────────┼───────┼────────┤ │ NB_DGRAM_TYPE │ type of datagrams to receive │ int │ value │ └──────────────────────┴────────────────────────────────┴───────┴────────┘ The following option is recognized for option level NBPROTO_NBP and is supported for the NetBIOS communication domain only. Option Description NB_DGRAM_TYPE (datagram sockets only) Gets type of datagrams to be received on the socket. The possible values are: NB_DGRAM The socket is to receive normal (unicast) datagrams only. NB_BROADCAST The socket is to receive broadcast datagrams only. NB_DGRAM_ANY The socket can receive both normal or broadcast datagrams. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using optval and optlen parameters results in an attempt to access memory outside the caller address space. SOCEINVAL The level parameter is not recognized. SOCENOPROTOOPT The optname parameter is not recognized. SOCENOTSOCK The s parameter is not a valid socket descriptor. Examples: The following are examples of the getsockopt() call. See setsockopt() for examples of how setsockopt() sets the socket options. int rc; int s; int optval; int optlen; struct linger lstruct; int getsockopt(int s, int level, int optname, char *optval, int *optlen); /* extracted from sys\socket.h */ . . . /* Is out of band data in the normal input queue? */ optlen = sizeof(int); rc = getsockopt( s, SOL_SOCKET, SO_OOBINLINE, (char *) &optval, &optlen); if (rc == 0) { if (optlen == sizeof(int)) { if (optval) /* yes it is in the normal queue */ else /* no it is not */ } } . . . /* Do I linger on close? */ optlen = sizeof(lstruct); rc = getsockopt( s, SOL_SOCKET, SO_LINGER, (char *) &lstruct, &optlen); if (rc == 0) { if (optlen == sizeof(lstruct)) { if (lstruct.l_onoff) /* yes I linger */ else /* no I do not */ } } ═══ 6.7. ioctl() ═══ Performs special operations on socket. #include #include #include #include #include #include int ioctl(s, cmd, data, lendata) int s; int cmd; caddr_t data; int lendata; Parameter Description s Socket descriptor cmd Command to perform data Pointer to the data associated with cmd lendata Length of the data in bytes Description: This call controls the operating characteristics of sockets. The data parameter is a pointer to data associated with the particular command, and its format depends on the command that is requested. Internet: The following ioctl commands are supported for the internet domain: Command Description FIOASYNC This command has no affect. FIONBIO Sets or clears nonblocking input/output for a socket. When this option is set, input/output calls do not block until the call is completed. The data parameter is a pointer to an integer. If the integer is 0, nonblocking input/output on the socket is cleared. Otherwise, the socket is set for nonblocking input/output. FIONREAD Gets the number of immediately readable bytes for the socket, and returns this value in an integer pointed to by the data parameter. SIOCATMARK Queries whether the current location in the data input is pointing to out-of-band data, and returns this value in an integer pointed to by the data parameter. An integer value of 1 indicates the socket points to a mark in the data stream for out-of-band data. Otherwise, the integer value is 0. SIOCGIFADDR Gets the network interface address, and returns this value in an ifreq structure pointed to by the data parameter. SIOCGIFBRDADDR Gets the network interface broadcast address, and returns this value in an ifreq structure pointed to by the data parameter. SIOCGIFCONF Gets the network interface configuration, and returns this value in an ifconf structure pointed to by the data parameter. SIOCGIFDSTADDR (stream sockets only) Gets the network interface destination address, and returns this value in an ifreq structure pointed to by the data parameter. SIOCGIFFLAGS Gets the network interface flags, and returns these values in an ifreq structure pointed to by the data parameter. SIOCGIFMETRIC (stream sockets only) Gets the network interface routing metric, and returns this value in an ifreq structure pointed to by the data parameter. SIOCGIFNETMASK Gets the network interface network mask, and returns this value in an ifreq structure pointed to by the data parameter. SIOCSIFADDR (stream sockets only) Sets the network interface address to the value passed in an ifreq structure pointed to by the data parameter. SIOCSIFBRDADDR (stream sockets only) Sets the network interface broadcast address to the value passed in an ifreq structure pointed to by the data parameter. SIOCSIFDSTADDR (stream sockets only) Sets the network interface destination address to the value passed in an ifreq structure pointed to by the data parameter. NetBIOS: The following ioctl commands are supported for the NetBIOS domain: Command Description FIONBIO Sets or clears nonblocking input/output for a socket. When this option is set, input/output calls do not block until the call is completed. The data parameter is a pointer to an integer. If the integer is 0, nonblocking input/output on the socket is cleared. Otherwise, the socket is set for nonblocking input/output. Local IPC: The following ioctl commands are supported for the Local IPC domain: Command Description FIONBIO Sets or clears nonblocking input/output for a socket. When this option is set, input/output calls do not block until the call is completed. The data parameter is a pointer to an integer. If the integer is 0, nonblocking input/output on the socket is cleared. Otherwise, the socket is set for nonblocking input/output. struct ifreq: The ifreq structure is defined in the header file. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using data and lendata results in an attempt to access memory outside the caller address space. SOCEINVAL The request is not valid or not supported. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCENXIO No such device or address. Possibly trying to get interface information on the wrong device. SOCEOPNOTSUPP The operation is not supported on the socket. Example: The following is an example of the ioctl() call. int s; int dontblock; int rc; int ioctl(int s, int cmd, caddr_t data, int lendata); /* extracted from sys\socket.h */ . . . /* Place the socket into nonblocking mode */ dontblock = 1; rc = ioctl(s, FIONBIO, (char *) &dontblock, sizeof(dontblock)); . . . ═══ 6.8. listen() ═══ Completes the binding necessary for a socket to accept connections and creates a connection request queue for incoming requests. #include #include int listen(s, backlog) int s; int backlog; Parameter Description s Socket descriptor. backlog Specifies the maximum limit of pending connections that can be queued on this socket. Description: The listen() call performs two tasks: completes the binding necessary for a socket s, if bind() has not been called for s and creates a connection request queue of length backlog to queue incoming connection requests. When the queue is full, additional connection requests are ignored. The listen() call indicates a readiness to accept client connection requests. It transforms an active socket into a passive socket. After listen() is called, s can never be used as an active socket to initiate connection requests. Listen() is called after allocating a socket with socket() and after binding a name to s with bind(). Listen() must be called before calling ACCEPT(). Listen() can be called on stream and sequenced packet sockets only. If the backlog parameter is less than 0, listen() interprets backlog as 0. If the backlog parameter is greater than SOMAXCONN, as defined in the header file, listen() interprets backlog as SOMAXCONN. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEOPNOTSUPP The s parameter is not a socket descriptor that supports the listen() call. ═══ 6.9. psock_errno() ═══ Writes a short error message to the standard error device. #include void psock_errno(s) char *s; Parameter Description s Pointer to a buffer Description: This call writes a short error message to the standard error display describing the last error encountered during a call to a socket library function on this thread. If s is not a NULL pointer and does not point to a null string, the string it points to is printed, followed by a colon, followed by a space, followed by the message. If s is a NULL pointer or points to a null string, only the message is printed. You can get the specific error code by calling sock_errno(). The error code is set when errors occur. Subsequent socket calls do not clear the error code. ═══ 6.10. readv() ═══ Receives data on a socket into a set of buffers. #include #include int readv(s, iov, iovcnt) int s; struct iovec *iov; int iovcnt; Parameter Description s Socket descriptor. iov Pointer to an array of iovec structures. iovcnt Number of iovec structures pointed to by the iov parameter. The maximum number of iovec structures is 32. Description: This call reads data on a socket with descriptor s and stores it in a set of buffers. The data is scattered into the buffers specified by iov[0]...iov[iovcnt-1]. The iovec structure is defined in the header file and contains the following fields: Field Description iov_base Points to the buffer iov_len Length of the buffer The readv() call applies to connected sockets only. For information on how to use readv() with datagram and raw sockets, see "Datagram or raw sockets".. This call returns up to the number of bytes in the buffers pointed to by the iov parameter. This number is the sum of all iov_len fields. If less than the number of bytes requested is available, the call returns the number currently available. If data is not available at the socket with descriptor s, the readv() call waits for data to arrive and blocks the caller, unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Return and sock_errno() Values: If successful, the return value is the number of bytes read into the buffers. The return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using iov and iovcnt results in an attempt to access memory outside the caller address space. SOCEINVAL iovcnt was not valid, or one of the fields in the iov array was not valid. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and no data is available to read, OR the SO_RCVTIMEO option has been set for socket s and the timeout expired before any data arrived to read. ═══ 6.11. recv() ═══ Receives data on a connected socket. #include #include int recv(s, buf, len, flags) int s; char *buf; int len; int flags; Parameter Description s Socket descriptor. buf Pointer to the buffer that receives the data. len Length of the buffer in bytes pointed to by the buf parameter. flags Set by specifying one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported for sockets in the internet domain only. MSG_OOB Reads any out-of-band data on the socket. MSG_PEEK Peeks at the data present on the socket; the data is returned but not consumed, so that a subsequent receive operation returns the same data. Description: This call receives data on a socket with descriptor s and stores it in the buffer pointed to by buf. The recv() call applies to connected sockets only. For information on how to use recv() with datagram and raw sockets, see "Datagram or raw sockets".. The recv() call returns the length of the incoming data. If a datagram is too long to fit in the buffer, the excess is discarded. No data is discarded for stream sockets. If data is not available at the socket with descriptor s, the recv() call waits for a message to arrive and blocks the caller, unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Return and sock_errno() Values: If successful, the return value is the length of the data, in bytes. The return value 0 indicates that the connection is closed. The return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using the buf and len parameters results in an attempt to access memory outside the caller address space. SOCEINVAL One of the parameters has an invalid value. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and no data is available to receive, or the SO_RCVTIMEO option has been set for socket s and the timeout expired before any data arrived to receive. ═══ 6.12. recvfrom() ═══ Receives data on a socket. #include #include int recvfrom(s, buf, len, flags, name, namelen) int s; char *buf; int len; int flags; struct sockaddr *name; int *namelen; Parameter Description s Socket descriptor. buf Pointer to the buffer that receives the data. len Length of the buffer in bytes pointed to by the buf parameter. flags Set by specifying one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported for sockets in the internet domain only. MSG_OOB Reads any out-of-band data on the socket. MSG_PEEK Peeks at the data present on the socket; the data is returned but not consumed, so that a subsequent receive operation returns the same data. name Pointer to a sockaddr structure (buffer) containing the source address of the data. If name is a nonzero value, the source address is returned. namelen Pointer to the size in bytes of the buffer pointed to by name. Description: The recvfrom() call receives data on a socket with descriptor s and stores it in a buffer. The recvfrom() call applies to any socket type, whether connected or not. If name is nonzero, the address of the data sender is returned. The namelen parameter is first initialized to the size of the buffer associated with name; on return, it is modified to indicate the actual number of bytes stored there. The recvfrom() call returns the length of the incoming message or data. If a datagram is too long to fit in the supplied buffer, the excess is discarded. No data is discarded for stream sockets. If data is not available at the socket with descriptor s, the recvfrom() call waits for a message to arrive and blocks the caller, unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Return and sock_errno() Values: If successful, the return value is the length of the data, in bytes. The return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using the buf and len parameters results in an attempt to access memory outside the caller address space. SOCEINVAL One of the parameters has an invalid value. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and no data is available to receive, or the SO_RCVTIMEO option has been set for socket s and the timeout expired before any data arrived to receive. ═══ 6.13. recvmsg() ═══ Receives data and control information on a specified socket. #include #include int recvmsg(s, msg, flags) int s; struct msghdr *msg; int flags; Parameter Description s Socket descriptor. msg Pointer to a message header that receives the message. flags Set by specifying one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported for sockets in the internet domain only. MSG_OOB Reads any out-of-band data on the socket. MSG_PEEK Peeks at the data present on the socket; the data is returned, but not consumed, so that a subsequent receive operation returns the same data. Description: This call receives a message on a socket with descriptor s. Parameter Description msg_name The optional pointer to the buffer containing the recipient address msg_namelen The size of the address buffer msg_iov An array of iovec buffers containing the message msg_iovlen The number of elements in the msg_iov array msg_accreights The access rights recived. This field is ignored. msg_accrightslen The length of the access right received. This field is ignored. The recvmsg() call applies to connection-oriented or connectionless sockets. This call returns the length of the data received. If a datagram is too long to fit in the supplied buffer, the excess is discarded. No data is discarded for stream sockets. If data is not available at the socket with descriptor s, the recvmsg() call waits for a message to arrive and blocks the caller, unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Return and sock_errno() Values: If successful, the return value is the length of the message, in bytes. The return value 0 indicates the connection is closed; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using msg results in an attempt to access memory outside the caller address space. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode, and no data is available to receive, or the SO_RCVTIMEO option has been set for socket s and the timeout expired before any data arrived to receive. ═══ 6.14. select() ═══ Gets read, write, and exception status on a group of sockets. Network Services supports two versions of the select() call:  OS/2 Version  Berkeley Software Distributions (BSD) Version Either version of select() can be used. The OS/2 version has better performance. However, the BSD version is more portable. ═══ 6.14.1. OS/2 Version ═══ In the OS/2 version, the socket numbers are specified as an array of integers, in which the read socket numbers are followed by write socket numbers, followed by the exception pending condition socket numbers. This version monitors the activity on a socket by specifying the number of sockets to be checked for readability, readiness for writing, and exception pending conditions. #include #include int select(s, noreads, nowrites, noexcepts, timeout) int *s; int noreads; int nowrites; int noexcepts; long timeout; Parameter Description s Pointer to an array of socket numbers where the read socket numbers are followed by the write socket numbers, and then followed by the exception socket numbers. noreads Number of sockets to be checked for readability. nowrites Number of sockets to be checked for readiness for writing. noexcepts Number of sockets to be checked for exceptional pending conditions. For Network Services sockets, the only exceptional pending condition is the presence of out-of-band data in the receive buffer. timeout Maximum interval, in milliseconds, to wait for the selection to complete. Description: This call monitors activity on a set of different sockets until a timeout expires, to see if any sockets are ready for reading or writing, or if any exceptional conditions are pending. If the timeout value is 0, select() does not wait before returning. If the timeout value is -1, select() does not timeout, but returns when a socket becomes ready. If the timeout value is a number of milliseconds, select() waits for the specified interval before returning. The select() call checks all indicated sockets at the same time and returns when any of them is ready. Return and sock_errno() Values: The return value is the number of ready sockets. The return value -1 indicates an error. The return value 0 indicates an expired time limit. If the return value is greater than 0, the socket numbers in s that were not ready are set to -1. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using the s parameter results in an attempt to access memory outside the caller address space. SOCEINTR Call interrupted. SOCEINVAL One of the parameters has an invalid value. SOCENOTSOCK The s parameter is not a valid socket descriptor. Examples: The following is an example of the OS/2 version of the select() call. #define MAX_TIMEOUT 1000 /* input_ready(insock)- Check to see if there is available input on * socket insock. * Returns 1 if input is available. * 0 if input is not available. * -1 on error. */ int input_ready(insock) int insock; /* input socket descriptor */ { int socks[1]; /* array of sockets */ long timeout = MAX_TIMEOUT; /* put socket to check in socks[] */ socks[0] = insock; /* check for READ availability on this socket */ return select(socks, 1, 0, 0, timeout); } ═══ 6.14.2. BSD Version ═══ The BSD version monitors the activity on sockets by specifying a set mask (fd_set) of socket numbers for which the caller wants to read the data, write the data, and check exception pending conditions. The BSD version provides FD_SET, FD_CLR, FD_ISSET, and FD_ZERO macros to add or delete socket numbers from the set mask. Note: You must define #define BSD_SELECT before including the Network Services header files to access the BSD version of the select() call. Otherwise, the OS/2 version is assumed. #define BSD_SELECT #include #include #include int select(nfds, readfds, writefds, exceptfds, timeout) int nfds; fd_set *readfds; fd_set *writefds; fd_set *exceptfds; struct timeval *timeout; Parameter Description nfds The range of socket descriptors to be checked. select() tests socket descriptors in the range of 0 to (nfds - 1). readfds Pointer to a bit mask of descriptors to be checked for reading. writefds Pointer to a bit mask of descriptors to be checked for writing. exceptfds Pointer to a bit mask of descriptors to be checked for exceptional pending conditions. For Network Services sockets, the only exceptional pending condition is the presence of out-of-band data in the receive buffer. timeout Pointer to the time to wait for the select() call to complete. Description: This call monitors activity on a set of different sockets until a timeout expires, to see if any sockets are ready for reading or writing, or if any exceptional conditions are pending. If timeout is a NULL pointer, the call blocks indefinitely until one of the requested conditions is satisfied. If timeout is non-NULL, it specifies the maximum time to wait for the call to complete. If the timeout parameter points to a zeroed timeval structure, a set of sockets is returned immediately. The timeval structure is defined in the header file and contains the following fields: Field Description tv_sec Number of seconds tv_usec Number of microseconds A bit mask is made up of an array of integers. Macros are provided to manipulate the bit masks. Macro Description FD_SET(socket, bit_mask_address) Sets the bit for the socket in the bit mask pointed to by bit_mask_address. FD_CLR(socket, bit_mask_address) Clears the bit. FD_ISSET(socket, bit_mask_address) Returns a non-zero value if the bit is set for this socket descriptor; otherwise, it returns zero. FD_ZERO(socket, bit_mask_address) Clears the entire bit mask for all socket descriptors. Notes 1. For macros FD_SET, FD_CLR, FD_ISSET, and FD_ZERO, define the parameters socket and bit_mask_address in the following manner: int socket; struct fd_set *bit_mask_address; 2. The first nfds descriptors in each bit mask are tested for the specified condition. 3. A socket descriptor with a value of 8 is actually the 9th descriptor in the fd_set (the socket descriptor value of 0 is the first descriptor). To check the socket descriptor 8, nfds would have to be greater than or equal to 9. 4. Socket descriptors are specified by setting bits in a bit mask. 5. Setting any of the descriptor pointers to zero indicates that no checks are to be made for the conditions. For example, setting exceptfds to be a NULL pointer causes the select call to check for read and write conditions only. Return and sock_errno() Values: The return value is the total number of ready sockets (in all bit masks). The return value -1 indicates an error. The return value 0 indicates an expired time limit. If the return value is greater than 0, the socket descriptors in each bit mask that are ready are set to 1. All others are set to 0. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT The address is not valid. SOCEINTR Call interrupted. SOCEINVAL One of the parameters has an invalid value. SOCENOTSOCK One of the sockets in the bit masks is not a valid socket descriptor. Examples: The following is an example of the BSD version of the select() call. #define BSD_SELECT . . . fd_set readsocks; fd_set writesocks; fd_set exceptsocks; struct timeval timeout; int read_socket; int write_socket; int max_socket; int number_found; . . . /* return immediately if nothing is ready */ timeout.tv_usec = 0; timeout.tv_sec = 0; /* initialize all the bitmasks to zero */ FD_ZERO(&readsocks); FD_ZERO(&writesocks); FD_ZERO(&exceptsocks); /* check for ability to read on read_sock, write on write_sock * don't care about exception conditions (OOB data) */ FD_SET(read_socket, &readsocks); FD_SET(write_socket, &writesocks); /* figure out the highest socket number to be checked in the bitmasks */ if (read_socket > write_socket) max_socket = read_socket; else max_socket = write_socket; /* issue the select, it returns number of sockets ready, * or -1 if none */ number_found = select(max_socket+1, &readsocks, &writesocks, &exceptsocks, &timeout); if (number_found > 0) { if (FD_ISSET(read_socket, &readsocks)) { /* can read data from read_socket */ } else if (FD_ISSET(write_socket, &writesocks)) { /* can write data on write_socket */ } } ═══ 6.15. send() ═══ Sends data on a connected socket. #include #include int send(s, msg, len, flags) int s; char *msg; int len; int flags; Parameter Description s Socket descriptor. msg Pointer to a buffer containing the message to transmit. len Length of the message pointed to by the msg parameter. flags Set by specifying one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported for sockets in the internet domain only. MSG_OOB Sends out-of-band data on sockets that support SOCK_STREAM communication. MSG_DONTROUTE The SO_DONTROUTE option is turned on for the duration of the operation. This is usually used only by diagnostic or routing programs. Description: This call sends data on the socket with descriptor s. The send() call applies to connected sockets. For information on how to use send() with datagram and raw sockets, see "Datagram or raw sockets".. If the socket send buffer does not have any space available of the address buffer to be sent, the send() call normally blocks, unless the socket is placed in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Use the select() call to determine when it is possible to send more data. Return and sock_errno() Values: If successful, the return value is the number of bytes sent. Successful completion does not guarantee delivery of the data to the receiver. The return value -1 indicates an error was detected on the sending side of the connection. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEDESTADDRREQ Destination address required. SOCEFAULT Using the msg and len parameters results in an attempt to access memory outside the caller address space. SOCEINVAL One of the parameters has an invalid value. SOCENOBUFS No buffer space is available to send the message. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and the data cannot be sent without blocking, or the SO_SNDTIMEO option has been set for socket s and the timeout expired before any data was sent. ═══ 6.16. sendmsg() ═══ Sends data and control information on a specified socket. #include #include int sendmsg(s, msg, flags) int s; struct msghdr *msg; int flags; Parameter Description s Socket descriptor. msg Pointer to a message header containing a message to be sent. flags Set by specifying one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported only for sockets in the internet domain. MSG_OOB Sends out-of-band data on the socket. MSG_DONTROUTE The SO_DONTROUTE option is turned on for the duration of the operation. This is usually used only by diagnostic or routing programs. Description: This call sends a msghdr structure on a socket with descriptor s. Parameter Description msg_name The optional pointer to the buffer containing the recipient address. msg_namelen The size of the address buffer. msg_iov An array of iovec buffers containing the message. msg_iovlen The number of elements in the msg_iov array. msg_accreights The access rights recived. This field is ignored. msg_accrightslen The length of the access right received. This field is ignored. The sendmsg() call applies to any socket. This call returns the length of the data sent. If the socket with descriptor s is not ready for sending data, the sendmsg() call waits unless the socket is in nonblocking mode. See ioctl() for a description of how to set nonblocking mode. Return and sock_errno() Values: If successful, the return value is the number of bytes sent. Successful completion does not guarantee delivery of the data to the receiver. The return value -1 indicates an error was detected on the sending side of the connection. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using msg results in an attempt to access memory outside the caller address space. SOCEINVAL msg_namelen is not the size of a valid address for the specified address family. SOCEMSGSIZE The message was larger than the size of the socket send buffer and could not be sent as a single datagram. SOCENOBUFS No buffer space is available to send the message. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and the data cannot be sent without blocking, or the SO_SNDTIMEO option has been set for socket s and the timeout expired before any data was sent. ═══ 6.17. sendto() ═══ Sends data on a socket. #include #include int sendto(s, msg, len, flags, to, tolen) int s; char *msg; int len; int flags; struct sockaddr *to; int tolen; Parameter Description s Socket descriptor. msg Pointer to the buffer containing the message to transmit. len Length of the message in the buffer pointed to by the msg parameter. flags Set to 0 or one or more of the following flags. If you specify more than one flag, use the logical OR operator (|) to separate them. Setting this parameter is supported only for sockets in the internet domain. MSG_OOB Sends out-of-band data on the socket. MSG_DONTROUTE The SO_DONTROUTE option is turned on for the duration of the operation. This is usually used only by diagnostic or routing programs. to Pointer to a sockaddr structure (buffer) containing the destination address. tolen Size in bytes of the buffer pointed to by the to parameter. Description: This call sends data on the socket with descriptor s. The sendto() call applies to connected or unconnected sockets. For unconnected datagram and raw sockets, the sendto() call sends data to the specified destination address. For stream and sequenced packet sockets, the destination address is ignored. Datagram sockets are connected by calling connect(). This identifies the peer to send or receive the datagram. After a datagram socket is connected to a peer, you can still use the sendto() call, but a destination address cannot be included. To change the peer address when using connected datagram sockets, issue a connect() call with a null address. Specifying a null address on a connected datagram socket removes the peer address specification. You can 1 address or issue a connect() call to connect to a different peer. For more information on connecting datagram sockets and specifying null addresses, see "Datagram or raw sockets".. Return and sock_errno() Values: If successful, the return value is the number of bytes sent. Successful completion does not guarantee delivery of the data to the receiver. The return value -1 indicates an error was detected on the sending side. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Descriptioun SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEDESTADDRREQ Destination address required. SOCEFAULT Using the msg and len parameters results in an attempt to access memory outside the caller address space. SOCEINVAL The tolen parameter is not the size of a valid address for the specified address family. SOCEMSGSIZE The message was larger than the size of the socket send buffer and could not be sent as a single datagram. SOCENOBUFS No buffer space is available to send the message. SOCENOTCONN The socket is not connected. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and the data cannot be sent without blocking, or the SO_SNDTIMEO option has been set for socket s and the timeout expired before any data was sent. ═══ 6.18. setsockopt() ═══ Sets options associated with a socket. #include #include int setsockopt(s, level, optname, optval, optlen) int s; int level; int optname; char *optval; int optlen; Parameter Description s Socket descriptor level Specifies the option level that is being set optname Name of a specified socket option optval Pointer to the option data optlen Length of the option data Description: This call sets options associated with a socket such as enabling debugging at the socket or protocol level, control timeouts, or permit socket data broadcast. Options can exist at the socket or the protocol level; options are always present at the highest socket level. When setting socket options, the level of the option and the name of the option must be specified. The following table lists the supported levels: ┌─────────────────────────────────────────────────┐ │ Table 15. Supported Levels │ ├──────────────────────┬──────────────────────────┤ │ SUPPORTED LEVEL │ #DEFINE IN │ ├──────────────────────┼──────────────────────────┤ │ SOL_SOCKET │ │ ├──────────────────────┼──────────────────────────┤ │ IPPROTO_IP │ │ ├──────────────────────┼──────────────────────────┤ │ IPPROTO_TCP │ │ ├──────────────────────┼──────────────────────────┤ │ NBPROTO_NB │ │ └──────────────────────┴──────────────────────────┘ The optval and optlen parameters are used to pass data used by the particular set command. The optval parameter points to a buffer containing the data needed by the set command. The optval parameter is optional and if data is not needed by the command, can be set to the NULL pointer. The optlen parameter must be set to the size of the data or data type pointed to by optval. For socket options that are boolean, the option is enabled if optval is nonzero and disabled if optval is zero. The following tables list the supported options for setsockopt() at each level (SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP, NBPROTO_NB). Detailed descriptions of the options follow each table. ┌────────────────────────────────────────────────────────────────────────┐ │ Table 16. Supported setsockopt() Socket Options for SOL_SOCKET │ ├──────────────┬──────────────────────────┬──────────┬────────┬──────────┤ │ │ │ DOMAINS │ DATA │ BOOLEAN │ │ OPTION NAME │ DESCRIPTION │ * │ TYPE │ OR VALUE │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_BROADCAST │ allows sending of broad- │ I, N │ int │ boolean │ │ │ cast messages │ │ │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_DEBUG │ turns on recording of │ I, L │ int │ boolean │ │ │ debugging information │ │ │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_DONTROUTE │ bypasses routing tables │ I, L │ int │ boolean │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_KEEPALIVE │ keeps connections alive │ I │ int │ boolean │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_LINGER │ lingers on close if data │ I │ struct │ value │ │ │ present │ │ linger │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_OOBINLINE │ leaves received OOB data │ I │ int │ boolean │ │ │ in-line │ │ │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVBUF │ receives buffer size │ I, L, N │ long │ value │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVLOWAT │ receives low-water mark │ I, L │ int │ value │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_RCVTIMEO │ receives timeout │ I, L, N │ struct │ value │ │ │ │ │ timeval│ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_REUSEADDR │ allows local address │ I, N │ int │ boolean │ │ │ reuse │ │ │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_REUSEPORT │ allows a socket to reuse │ I │ int │ boolean │ │ │ a local address and │ │ │ │ │ │ local port │ │ │ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDBUF │ sends buffer size │ I, L, N │ long │ value │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDLOWAT │ sends low-water mark │ I. L │ int │ value │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ │ SO_SNDTIMEO │ sends timeout │ I, L, N │ struct │ value │ │ │ │ │ timeval│ │ ├──────────────┼──────────────────────────┼──────────┼────────┼──────────┤ ├──────────────┴──────────────────────────┴──────────┴────────┴──────────┤ │ NOTE: * This column specifies I for internet, L for Local IPC, and N │ │ for NetBIOS communication domains. │ └────────────────────────────────────────────────────────────────────────┘ The following options are recognized for option level SOL_SOCKET: Option Description SO_BROADCAST (datagram sockets only) Sets the ability to broadcast messages. If this option is enabled, it allows the application to send broadcast messages over s, if the interface specified in the destination supports broadcasting of packets. SO_DEBUG Sets the ability to record debug information for a socket. SO_DONTROUTE Sets the ability for the socket to bypass the routing of outgoing messages. When this option is enabled, it causes outgoing messages to bypass the standard routing algorithm and be directed to the appropriate network interface according to the network portion of the destination address. When enabled, packets can be sent to directly connected networks (networks for which this host has an interface) only. SO_KEEPALIVE (stream sockets only) Sets the ability of the socket to send keepalive packets that keep the connection alive. TCP uses a timer called the keepalive timer. This timer is used to monitor idle connections that may have been disconnected because of a peer crash or timeout. If this option is set to ON, a keepalive packet is periodically sent to the peer. This is mainly used to allow servers to close connections that are no longer active as a result of clients going away without properly closing connections. SO_LINGER (stream sockets only) Sets the ability of the socket to linger on close. When this option is enabled, and data is present in the socket send buffer when soclose() is called, the calling appl ication is blocked in soclose() until the data is transmitted or until the linger timeout expires. If the linger timeout expires, the unsent data is discarded, the connection is reset, and soclose() returns -1 with an error value of SOCEWOULDBLOCK. Even though soclose() returned an error, the socket is closed (no further calls can be made for the socket). Note that a linger timeout of zero results in no lingering if unsent data exists. A timeout of zero expires immediately when the call is issued, resulting in discarding any unsent data and resetting the connection. When this option is disabled (the default), soclose() does not block when unsent data is present at the time of the call. Rather, the soclose() completes immediately and TCP continues to attempt to send the remaining data before closing the connection. The application has no guarantee that the data is successfully sent, since errors encountered on the connection after the socket is closed cannot be reported to the application. SO_OOBINLINE (stream sockets only) Sets the ability of the socket to receive out-of-band data. As stated in TCP/IP Illustrated, Volume 1: The Protocols out-of-band data is "a logically separate data path using the same connection as the normal data path." When this option is enabled, it causes out-of-band data to be placed in the normal data input queue as it is received, making it available to recv(), and recvfrom(), without having to specify the MSG_OOB flag in those calls. When this option is disabled, it causes out-of-band data to be placed in the priority data input queue as it is received, making it available to recv(), and recvfrom(), only by specifying the MSG_OOB flag in those calls. SO_RCVBUF Sets buffer size for input. This option sets the size of the receive buffer to the value contained in the buffer pointed to by optval. This allows the buffer size to be tailored for specific application needs, such as increasing the buffer size for high-volume connections. SO_RCVLOWAT Sets receive low-water mark that controls when a recv() call returns when less data is available than the recv() call is requesting. If at least SO_RCVLOWAT bytes are available, the recv() call returns those bytes. The default is 1 for both TCP and UDP sockets. SO_RCVTIMEO Sets receive timeout. This value limits the length of a blocking receive call. This value is ignored for non-blocking calls. SO_REUSEADDR (stream and datagram sockets only) Allows a socket to reuse a local address. When enabled, this option allows local addresses that are already in use to be bound. This alters the normal algorithm used in the bind() call. Network Services checks at connect time to be sure that no local address and port have the same foreign address and port. The error SOCEADDRINUSE is returned if the association already exists. SO_REUSEPORT (stream and datagram sockets only) Allows a socket to reuse a local address and port. When enabled, this option allows local addresses and ports that are already in use to be bound. This alters the normal algorithm used in the bind() call. This option is normally only used by multicasting applications. SO_SNDBUF Sets buffer size for output. This option sets the size of the send buffer to the value contained in the buffer pointed to by optval. This allows the send buffer size to be tailored for specific application needs, such as increasing the buffer size for high-volume connections. SO_SNDLOWAT Sets send low-water mark that influences socket flow control operations. SO_SNDLOWAT is used for TCP sockets, but not UDP sockets. During a send operation, if the socket code must wait for space to be available in the send buffer before sending data, the socket waits for at least SO_SNDLOWAT bytes to be available in the send buffer before sending the data. The default value is the size of a cluster mbuf. SO_SNDTIMEO Sets send timeout. This value limits the length of a blocking send call. This value is ignored for non-blocking calls. struct linger: For the SO_LINGER option, optval points to a linger structure. This structure is defined in and contains the following fields: Field Description l_onoff Option on/off l_linger Linger time The l_onoff field is set to zero if the SO_LINGER option is being disabled. A nonzero value enables the option. The l_linger field specifies the amount of time in seconds to linger on close. A value of zero causes an abnormal close. TCP discards any data still queued to be sent on the connection and sends a reset to the peer. The peer sees this as an abnormal close when it gets an error on an outstanding receive. struct timeval: For the SO_RCVTIMEO and SO_SNDTIMEO options, optval points to a timeval structure. This structure is defined in and contains the following fields: Field Description tv_sec Number of seconds tv_usec Number of microseconds For the internet domain, the finest resolution is milliseconds, thus the tv_usec field is converted. In this conversion, anything less than a millisecond is truncated. For example, if you call setsockopt() to set tv_usec to 31, the next getsockopt() call returns a 0 for tv_usec If you call setsockopt() to set tv_usec to 1031, the next getsockopt() returns 1000. ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Table 17. Supported setsockopt() Socket Options for IPPROTO_IP │ ├──────────────────────┬────────────────────────────────┬──────────────┬──────────┤ │ │ │ │ BOOLEAN │ │ OPTION NAME │ DESCRIPTION │ DATA TYPE │ OR VALUE │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_ADD_MEMBERSHIP │ joins a multicast group │ struct │ value │ │ │ │ ip_mreq │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_DROP_MEMBERSHIP │ leaves a multicast group │ struct │ value │ │ │ │ ip_mreq │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_MULTICAST_IF │ provides default interface for │ struct │ value │ │ │ outgoing multicasts │ in_addr │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_MULTICAST_LOOP │ causes a loopback of outgoing │ uchar │ boolean │ │ │ multicast │ │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_MULTICAST_TTL │ provides default TTL for out- │ uchar │ value │ │ │ going multicast │ │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_OPTIONS │ provides options in IP header │ void * │ value │ │ │ to be included in outgoing │ │ │ │ │ datagrams │ │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_RECVDSTADDR │ allows queueing of IP destina- │ int │ boolean │ │ │ tion address │ │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_TOS │ gives type of service for out- │ int │ boolean │ │ │ going datagrams │ │ │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ IP_TTL │ provides time to live for out- │ int │ value │ │ │ going datagrams │ │ │ └──────────────────────┴────────────────────────────────┴──────────────┴──────────┘ The following options are recognized for option level IPPROTO_IP and are supported for the internet communication domain only. Option Description IP_ADD_MEMBERSHIP Sets to join a multicast group. Specify the IP multicast address and the local IP address of the interface. If the interface address is INADDR_ANY, the interface picked is based on the routing table. IP_DROP_MEMBERSHIP Sets to leave a multicast group. Specify the IP multicast address and the local IP address of the interface. If the interface address is INADDR_ANY, all interfaces are searched for this IP multicast address. IP_MULTICAST_IF Sets the default interface for outgoing multicasts. Normally this is the interface selected for an outgoing interface based on the destination. This default can be overridden by specifying the IP address of the outgoing interface. IP_MULTICAST_LOOP Enables or disables loopback of outgoing multicasts. If this value is set to 0, packets are not looped back and delivered to the transmitting interface, even if the interface is a member of the multicasting group. If this value is set to 1, packets are looped back if the interface is a member of the multicasting group. The default value is 1. IP_MULTICAST_TTL Sets the default TTL for outgoing multicasts. The default is 1, which causes multicast datagrams to remain on the local network. This value is also used by multicast routers to have a threshold policy to drop multicast packets. Packets can be dropped by a router even though its TTL is not 0. IP_OPTIONS Sets options in the IP header to be included in outgoing datagrams. IP_RECVDSTADDR (datagram sockets only) Enables or disables if IP destination address is passed on the recvmsg() call. The IP destination is passed pack in the msg_control parameter, if the msg_controllen parameter is less than 4 bytes, the flags indicate the control information was truncated. IP_TOS Sets the type of service (TOS) used in outgoing datagram and stream packets. IP_TTL Sets the time to live (TTL) for outgoing datagrams. A TTL value of 1 prevents packets from being routed to other networks. Raw sockets default to the maximum of 255, datagram and stream sockets default to 64. ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Table 18. Supported setsockopt() Socket Options for IPPROTO_TCP │ ├──────────────────────┬────────────────────────────────┬──────────────┬──────────┤ │ │ │ │ BOOLEAN │ │ OPTION NAME │ DESCRIPTION │ DATA TYPE │ OR VALUE │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ TCP_NODELAY │ indicates that the send to │ int │ boolean │ │ │ coalesce packets should not be │ │ │ │ │ delayed │ │ │ └──────────────────────┴────────────────────────────────┴──────────────┴──────────┘ The following options are recognized for option level IPPROTO_TCP and are supported for the internet communication domain only.  TCP_ socket options  IPPROTO_TCP socket options Option Description TCP_NODELAY (stream sockets only) Setting on disables the small packet avoidance algorithm so that the client TCP sends small packets as soon as possible. This option may provide a performance improvement for some applications on a LAN, but can degrade performance on Wide Area Networks (WAN). ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Table 19. Supported setsockopt() Socket Options for NBPROTO_NB │ ├──────────────────────┬────────────────────────────────┬──────────────┬──────────┤ │ │ │ │ BOOLEAN │ │ OPTION NAME │ DESCRIPTION │ DATA TYPE │ OR VALUE │ ├──────────────────────┼────────────────────────────────┼──────────────┼──────────┤ │ NB_DGRAM_TYPE │ type of datagrams to receive │ int │ value │ └──────────────────────┴────────────────────────────────┴──────────────┴──────────┘ The following option is recognized for option level NBPROTO_NB and is supported for the NetBIOS communication domain only. Option Description NB_DGRAM_TYPE (datagram sockets only) Sets type of datagrams to be received on the socket. The possible values are: NB_DGRAM The socket is to receive normal (unicast) datagrams only. NB_BROADCAST The socket is to receive broadcast datagrams only. NB_DGRAM_ANY The socket can receive both normal or broadcast datagrams. This option can be changed at any time. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEFAULT Using optval and optlen parameters results in an attempt to access memory outside the caller address space. SOCEINVAL One of the parameters has an invalid value. SOCENOBUFS No buffer space is available. SOCENOPROTOOPT The optname parameter or the level parameter is unrecognized. SOCENOTSOCK The s parameter is not a valid socket descriptor. Examples: The following are examples of the setsockopt() call. See getsockopt() for examples of how getsockopt() retrieves the socket option settings. int rc; int s; int optval; struct linger lstruct; /* extracted from sys/socket.h */ int setsockopt(int s, int level, int optname, char *optval, int optlen); . . . /* I want out of band data in the normal input queue. */ optval = 1; rc = setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *) &optval, sizeof(int)); . . . /* I want to linger on close. */ lstruct.l_onoff = 1; lstruct.l_linger = 100; rc = setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &lstruct, sizeof(lstruct)); ═══ 6.19. shutdown() ═══ Shuts down all or part of a full-duplex connection. int shutdown(s, howto) int s; int howto; Parameter Description s Socket descriptor howto Condition of the shutdown Description: This call shuts down all or part of a full-duplex connection. Because data flows in one direction are independent of data flowing from the other direction, the shutdown call allows data flow to be stopped independently in either direction or all data flows with one API call. For example, you may want to stop the senders from sending data to you, but you still want to send data. Using the shutdown() call is optional. The howto parameter sets the condition for shutting down the connection to socket s. It can be set to one of the following:  0 - no more data can be received on socket s.  1 - no more data can be sent on socket s.  2 - no more data can be sent or received on socket s. Note: In the NetBIOS domain, the shutdown() call is valid, but the function of shutdown() is not implemented. When called, shutdown() returns a successful return code, but no shutdown occurs. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEINVAL The howto parameter was not set to one of the valid values. SOCENOTSOCK The s parameter is not a valid socket descriptor. ═══ 6.20. sock_errno() ═══ Returns error code set by a socket call. #include int sock_errno() Description: The sock_errno() call returns the last error code set by a socket call on this thread. ═══ 6.21. socket() ═══ Creates an endpoint for communication and returns a socket descriptor representing the endpoint. #include #include int socket(domain, type, protocol) int domain; int type; int protocol; Parameter Description domain Communication domain requested type Type of socket created protocol Protocol requested Description: This call creates an endpoint for communication and returns a socket descriptor representing the endpoint. Each socket type provides a different communication service. Sockets are deallocated with the soclose() call. The domain parameter specifies a communications domain where communication is to take place. This parameter specifies the protocol family that is used. Protocol Family Description AF_OS2, AF_UNIX, or AF_LOCAL Use addresses in the Local IPC format that take the form of OS/2 Warp Connect file and path names. AF_INET Use addresses in the internet address format. AF_NETBIOS or AF_NB Use addresses in the NetBIOS address format. The type parameter specifies the type of socket created. The type is analogous with the semantics of the communication requested. These socket type constants are defined in the header file. Refer to Socket Types for additional details. The types supported are: Type Description SOCK_STREAM Provides sequenced, two-way byte streams that are reliable and connection-oriented. It supports a mechanism for out-of-band data. Stream sockets are supported by the internet (AF_INET) communication domain and Local IPC (AF_OS2, AF_UNIX, or AF_LOCAL). SOCK_SEQPACKET Provides sequenced, two-way byte records that are reliable and connection-oriented. Sequenced packet sockets are supported by the NetBIOS (AF_NETBIOS or AF_NB) communication domain. SOCK_DGRAM Provides datagrams, which are connectionless messages whose reliability is not guaranteed. Datagrams can be received out of order, lost, or delivered multiple times. Datagram sockets are supported by the internet (AF_INET), Local IPC (AF_OS2, AF_UNIX, or AF_LOCAL), and NetBIOS (AF_NETBIOS or AF_NB) communication domains. SOCK_RAW Provides the interface to internal protocols (such as IP and ICMP). Raw sockets are supported by the internet (AF_INET) communication domain. The protocol parameter specifies a particular protocol to be used with the socket. If the protocol field is set to 0 (default), Network Services selects the default protocol number for the domain and socket type requested. Default and valid protocol number-protocol family combinations are in Default Protocols. The getprotobyname() call can be used to get the protocol number for a protocol with a well-known name. Return and sock_errno() Values: A non-negative socket descriptor return value indicates success. The return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEMFILE The maximum number of sockets are currently in use. SOCEPROTONOSUPPORT The protocol is not supported in the specified domain or the protocol is not supported for the specified socket type. SOCEPROTOTYPE The protocol is the wrong type for the socket. Examples: The following are examples of the socket() call. int s; struct protoent *p; struct protoent *getprotobyname(char *name); int socket(int domain, int type, int protocol); /* extracted from sys\socket.h */ . . . /* Get stream socket in internet domain with default protocol. */ s = socket(AF_INET, SOCK_STREAM, 0); . . . /* Get raw socket in internet domain for ICMP protocol. */ p = getprotobyname("icmp"); s = socket(AF_INET, SOCK_RAW, p->p_proto); ═══ 6.22. soclose() ═══ Shuts down a socket and frees resources allocated to the socket. #include #include int soclose(s) int s; Parameter Description s Socket descriptor Description: This call shuts down the socket associated with the socket descriptor s, and frees resources allocated to the socket. If s refers to a connected socket, the connection is closed. If the SO_LINGER socket option is enabled (see setsockopt() for additional information), the task tries to send any queued data. If the SO_LINGER socket option is disabled, the task flushes any data queued to be sent. Return and sock_errno() Values: The return value 0 indicates success; the return value -1 indicates an error. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCENOTSOCK The s parameter is not a valid socket descriptor. SOCEWOULDBLOCK The linger option is enabled and the linger timeout expired before unsent data could be successfully sent. The data is discarded and the connection is reset instead of closing normally. ═══ 6.23. writev() ═══ Writes data from a set of specified buffers on a socket. #include #include int writev(s, iov, iovcnt) int s; struc iovec *iov; int iovcnt; Parameter Description s Socket descriptor. iov Pointer to an array of iovec structures. iovcnt Number of iovec structures pointed to by the iov parameter. The maximum number of iovec structures is 32. Description: This call writes data on a socket with descriptor s. The data is gathered from the buffers specified by iov[0]...iov[iovcnt-1]. The iovec structure is defined in the header file and contains the following fields: Field Description iov_base Pointer to the buffer iov_len Length of the buffer This call writes up to the number of bytes in the buffers pointed to by the iov parameter. This number is the sum of all iov_len fields. If the data cannot be sent without blocking and the socket is in blocking mode, the writev() call blocks the caller until the data can be sent. If the socket is in a nonblocking mode, writev() returns -1 and sets the return code to SOCEWOULDBLOCK. See ioctl() for a description of how to set nonblocking mode. For datagram sockets, this call sends the entire datagram, provided it fits into the socket write buffer. If the socket write buffer does not have any space available to hold the message to be written, the writev() call normally blocks, unless the socket is placed in nonblocking mode. Use the select() call to determine when it is possible to write more data. Return and sock_errno() Values: If successful, the return value is the number of bytes written. Successful completion does not guarantee the data is written. The return value -1 indicates an error was detected on the sending side of the connection. You can get the specific error code by calling sock_errno() or psock_errno(). sock_errno() Value Description SOCECOMMSYS Internal communications error. Contact IBM Service. SOCEDESTADDRREQ A destination address is required. SOCEFAULT Using the iov and iovcnt parameters results in an attempt to access memory outside the caller address space. SOCEINVAL One of the parameters has an invalid value. SOCEMSGSIZE The message was larger than the size of the socket send buffer and could not be sent as a single datagram. SOCENOBUFS No buffer space is available to send the message. SOCENOTCONN The socket is not connected. SOCENOTSOCK s is not a valid socket descriptor. SOCEWOULDBLOCK The s parameter is in nonblocking mode and the data cannot be written without blocking, or the SO_SNDTIMEO option has been set for socket s and the timeout expired before any data was sent. ═══ 7. TCP/IP Network Utility Routines ═══ The following table briefly describes each sockets utility function call supported by MPTS and identifies the location in the book where you can find the syntax, parameters, and other appropriate information. The following socket calls described in this section can be used to access services only for the internet communication domain: ┌────────────────────────────────────────────────────────────────────────────────┐ │ Table 20. TCP/IP Network Utility Routines Quick Reference │ ├──────────────────────┬─────────────────────────────────────────────────────────┤ │ SOCKET CALL │ DESCRIPTION │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ bswap() │ Swaps bytes in a short integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ dn_comp() │ Compresses the expanded domain name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ dn_expand() │ Expands a compressed domain name to a full domain name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ endhostent() │ Closes the HOSTS file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ endnetent() │ Closes the NETWORKS file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ endprotoent() │ Closes the PROTOCOL file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ endservent() │ Closes the SERVICES file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ gethostbyaddr() │ Returns a pointer to information about a host specified │ │ │ by an internet address │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ gethostbyname() │ Returns a pointer to information about a host specified │ │ │ by a host name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ gethostent() │ Returns a pointer to the next entry in the HOSTS file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ gethostid() │ Returns the unique identifier of the current host │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ gethostname() │ Gets the standard host name for the local host machine │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getnetbyaddr() │ Returns a pointer to the NETWORKS file entry that con- │ │ │ tains the specified network address │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getnetbyname() │ Returns a pointer to the NETWORKS file entry that con- │ │ │ tains the specified network name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getnetent() │ Returns a pointer to the next entry in the NETWORKS │ │ │ file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getprotobyname() │ Returns a pointer to the PROTOCOL file entry specified │ │ │ by a protocol name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getprotobynumber() │ Returns a pointer to the PROTOCOL file entry specified │ │ │ by a protocol number │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getprotoent() │ Returns a pointer to the next entry in the PROTOCOL │ │ │ file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getservbyname() │ Returns a pointer to the SERVICES file entry specified │ │ │ by a service name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getservbyport() │ Returns a pointer to the SERVICES file entry specified │ │ │ by a port number │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ getservent() │ Returns a pointer to the next entry in the SERVICES │ │ │ file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ htonl() │ Translates byte order from host to network for a long │ │ │ integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ htons() │ Translates byte order from host to network for a short │ │ │ integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_addr() │ Constructs an internet address from character strings │ │ │ representing numbers expressed in standard dotted- │ │ │ decimal notation │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_lnaof() │ Returns the local network portion of an internet │ │ │ address │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_makeaddr() │ Constructs an internet address from a network number │ │ │ and a local address │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_netof() │ Returns the network portion of the internet address in │ │ │ network-byte order │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_network() │ Constructs a network number from character strings │ │ │ representing numbers expressed in standard dotted- │ │ │ decimal notation │ └──────────────────────┴─────────────────────────────────────────────────────────┘ ┌────────────────────────────────────────────────────────────────────────────────┐ │ Table 20. TCP/IP Network Utility Routines Quick Reference │ ├──────────────────────┬─────────────────────────────────────────────────────────┤ │ SOCKET CALL │ DESCRIPTION │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ inet_ntoa() │ Returns a pointer to a string in dotted-decimal nota- │ │ │ tion │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ lswap() │ Swaps bytes in a long integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ ntohl() │ Translates byte order from network to host for a long │ │ │ integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ ntohs() │ Translates byte order from network to host for a short │ │ │ integer │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ res_init() │ Reads the RESOLV file for the default domain name │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ res_mkquery() │ Makes query message for the name servers in the │ │ │ internet domain │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ res_send() │ Sends query to a local name server │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ sethostent() │ Opens and rewinds the HOSTS file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ setnetent() │ Opens and rewinds the NETWORKS file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ setprotoent() │ Opens and rewinds the PROTOCOL file │ ├──────────────────────┼─────────────────────────────────────────────────────────┤ │ setservent() │ Opens and rewinds the SERVICES file │ └──────────────────────┴─────────────────────────────────────────────────────────┘ ═══ 7.1. bswap() ═══ Swaps bytes in a short integer. #include #include u_short bswap(a) u_short a; Parameter Description a Unsigned short integer whose bytes are to be swapped Description: This call swaps bytes in a short integer. Return Value: Returns the translated short integer. ═══ 7.2. dn_comp() ═══ Compresses the expanded domain name. #include #include #include #include int dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) u_char *exp_dn; u_char *comp_dn; int length; u_char **dnptrs; u_char **lastdnptr; Parameter Description exp_dn Pointer to the location of an expanded domain name comp_dn Pointer to an array containing the compressed domain name length Length of the array in bytes pointed to by the comp_dn parameter dnptrs List of pointers to previously compressed names in the current message lastdnptr Pointer to the end of the array pointed to by dnptrs Description: This call compresses the domain name pointed to by the exp_dn parameter and stores it in the area pointed to by the comp_dn parameter. It uses the global _res structure, which is defined in the header file. Return Value: When successful, the dn_comp() call returns the size of the compressed domain name. If it fails, the call returns a value of -1. ═══ 7.3. dn_expand() ═══ Expands a compressed domain name to a full domain name. #include #include #include #include int dn_expand(msg, eomorig, comp_dn, exp_dn, length) u_char *msg; u_char *eomorig; u_char *comp_dn; u_char *exp_dn; int length; Parameter Description msg Pointer to the beginning of a message eomorig Pointer to the end of the original message that contains the compressed domain name comp_dn Pointer to the compressed domain name exp_dn Pointer to a buffer that holds the resulting expanded domain name length Length of the buffer in bytes pointed to by the exp_dn parameter Description: This call expands a compressed domain name to a full domain name, converting the expanded name to all uppercase letters. It uses the global _res structure, which is defined in the header file. Return Value: If it succeeds, the dn_expand() call returns the size of the expanded domain name. If it fails, the call returns a value of -1. ═══ 7.4. endhostent() ═══ Closes the HOSTS file. void endhostent() Description: This call closes the ETC\HOSTS file, which contains information about known hosts. ═══ 7.5. endnetent() ═══ Closes the NETWORKS file. void endnetent() Description: The endnetent() call closes the ETC\NETWORKS file, which contains information about known networks. ═══ 7.6. endprotoent() ═══ Closes the PROTOCOL file. void endprotoent() Description: This call closes the ETC\PROTOCOL file, which contains information about known protocols. ═══ 7.7. endservent() ═══ Closes the SERVICES file. void endservent() Description: This call closes the ETC\SERVICES file, which contains information about known services. ═══ 7.8. gethostbyaddr() ═══ Returns a pointer to information about a host specified by an internet address. #include struct hostent *gethostbyaddr(addr, addrlen, addrfam) char *addr; int addrlen; int addrfam; Parameter Description addr Pointer to a 32-bit internet address in network-byte order addrlen Size of addr in bytes addrfam Address family supported (AF_INET) Description: This call resolves the host name through a name server, if one is present. If a name server is not present or cannot resolve the host name, gethostbyaddr() searches the ETC\HOSTS file in sequence until a matching host address is found or an end-of-file (EOF) marker is reached. Return Value: The return value points to static data that subsequent API calls can modify. This call returns a pointer to a hostent structure for the host address specified on the call and indicates success. A NULL pointer indicates an error or EOF. The header file defines the hostent structure and contains the following elements: Element Description h_name Official name of the host h_aliases Zero-terminated array of alternative names for the host h_addrtype The address family of the network address being returned, always set to AF_INET h_length Length of the address in bytes h_addr Pointer to the network address of the host The value of h_errno indicates the specific error. ┌─────────────────┬───────┬───────────────────────────────────────────────┐ │ H_ERRNO VALUE │ CODE │ DESCRIPTION │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ HOST_NOT_FOUND │ 1 │ The host specified by the addr parameter is │ │ │ │ not found. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ TRY_AGAIN │ 2 │ The local server does not receive a response │ │ │ │ from an authorized server. Try again later. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_RECOVERY │ 3 │ This error code indicates an unrecoverable │ │ │ │ error. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_DATA │ 4 │ The requested addr is valid, but does not │ │ │ │ have an internet address at the name server. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_ADDRESS │ 4 │ The requested addr is valid, but does not │ │ │ │ have an internet address at the name server. │ └─────────────────┴───────┴───────────────────────────────────────────────┘ ═══ 7.9. gethostbyname() ═══ Returns a pointer to information about a host specified by a host name. #include struct hostent *gethostbyname(name) char *name; Parameter Description name Pointer to the name of the host being queried Description: This call resolves the host name through a name server, if one is present. If a name server is not present or is unable to resolve the host name, gethostbyname() searches the ETC\HOSTS file in sequence until a matching host name is found or an EOF marker is reached. Return Value and h_errno Value: The return value points to static data that subsequent API calls can modify. This call returns a pointer to a hostent structure for the host address specified on the call and indicates success. A NULL pointer indicates an error or EOF. The header file defines the hostent structure and contains the following elements: Element Description h_name Official name of the host h_aliases Zero-terminated array of alternative names for the host h_addrtype The address family of the network address being returned, always set to AF_INET h_length Length of the address in bytes h_addr Pointer to the network address of the host The value of h_errno indicates the specific error. ┌─────────────────┬───────┬───────────────────────────────────────────────┐ │ H_ERRNO VALUE │ CODE │ DESCRIPTION │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ HOST_NOT_FOUND │ 1 │ The host specified by the name parameter is │ │ │ │ not found. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ TRY_AGAIN │ 2 │ The local server does not receive a response │ │ │ │ from an authorized server. Try again later. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_RECOVERY │ 3 │ This error code indicates an unrecoverable │ │ │ │ error. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_DATA │ 4 │ The requested name is valid, but does not │ │ │ │ have an internet address at the name server. │ ├─────────────────┼───────┼───────────────────────────────────────────────┤ │ NO_ADDRESS │ 4 │ The requested name is valid, but does not │ │ │ │ have an internet address at the name server. │ └─────────────────┴───────┴───────────────────────────────────────────────┘ ═══ 7.10. gethostent() ═══ Returns a pointer to the next entry in the HOSTS file. #include #include struct hostent *gethostent() Description: This call returns a pointer to the next entry in the HOSTS file. Return Value: The return value points to static data that subsequent API calls can modify. This call returns a pointer to a hostent structure for the host address specified on the call and indicates success. A NULL pointer indicates an error or EOF. The header file defines the hostent structure and contains the following elements: Element Description h_name Official name of the host h_aliases Zero-terminated array of alternative names for the host h_addrtype The address family of the network address being returned, always set to AF_INET h_length Length of the address in bytes h_addr Pointer to the network address of the host ═══ 7.11. gethostid() ═══ Returns the unique identifier of the current host. #include u_long gethostid() Description: This call gets the unique 32-bit identifier in network-byte order for the current host. Return Value: The gethostid() call returns the 32-bit identifier, in network-byte order of the current host, which should be unique across all hosts. ═══ 7.12. gethostname() ═══ Gets the standard host name for the local host machine. #include int gethostname(name, namelen) char *name; int namelen; Parameter Description name Pointer to a buffer namelen Length of the buffer Description: This call copies the standard host name for the local host into the buffer specified by the name parameter. The returned name is a null-terminated string. Return Value: The value 0 indicates success; the value -1 indicates an error. ═══ 7.13. getnetbyaddr() ═══ Returns a pointer to the NETWORKS file entry that contains the specified network address. #include struct netent *getnetbyaddr(net, type) u_long net; int type; Parameter Description net Network address type Address family supported (AF_INET) Description: The getnetbyaddr() call searches the ETC\NETWORKS file for the specified network address. Return Value: The return value points to static data that subsequent API calls can modify. A pointer to a netent structure indicates success. A NULL pointer indicates an error or EOF. The netent structure is defined in the header file and contains the following elements: Element Description n_name Official name of the network n_aliases An array, terminated with a NULL pointer, of alternative names for the network n_addrtype The address family of the network address being returned, always set to AF_INET n_net Network number, returned in host-byte order ═══ 7.14. getnetbyname() ═══ Returns a pointer to the NETWORKS file entry that contains the specified network name. #include struct netent *getnetbyname(name) char *name; Parameter Description name Pointer to a network name Description: This call searches the ETC\NETWORKS file for the specified network name. Return Value: The getnetbyname() call returns a pointer to a netent structure for the network name specified on the call. The return value points to static data that subsequent API calls can modify. A pointer to a netent structure indicates success. A NULL pointer indicates an error or EOF. The netent structure is defined in the header file and contains the following elements: Element Description n_name Official name of the network n_aliases An array, terminated with a NULL pointer, of alternative names for the network n_addrtype The address family of the network address being returned, always set to AF_INET n_net Network number, returned in host-byte order ═══ 7.15. getnetent() ═══ Returns a pointer to the next entry in the NETWORKS file. #include struct netent *getnetent() Description: This call returns a pointer to the next entry in the ETC\NETWORKS file. Return Value: The getnetent() call returns a pointer to the next entry in the ETC\NETWORKS file. The return value points to static data that subsequent API calls can modify. A pointer to a netent structure indicates success. A NULL pointer indicates an error or EOF. The netent structure is defined in the header file and contains the following elements: Element Description n_name Official name of the network n_aliases An array, terminated with a NULL pointer, of alternative names for the network n_addrtype The address family of the network address being returned, always set to AF_INET n_net Network number, returned in host-byte order ═══ 7.16. getprotobyname() ═══ Returns a pointer to the PROTOCOL file entry specified by a protocol name. #include struct protoent *getprotobyname(name) char *name; Parameter Description name Pointer to the specified protocol Description: This call searches the ETC\PROTOCOL file for the specified protocol name. Return Value: The getprotobyname() call returns a pointer to a protoent structure for the network protocol specified on the call. The return value points to static data that subsequent API calls can modify. A pointer to a protoent structure indicates success. A NULL pointer indicates an error or EOF. The protoent structure is defined in the header file and contains the following elements: Element Description p_name Official name of the protocol p_aliases Array, terminated with a NULL pointer, of alternative names for the protocol p_proto Protocol number ═══ 7.17. getprotobynumber() ═══ Returns a pointer to the PROTOCOL file entry specified by a protocol number. #include struct protoent * getprotobynumber(proto) int proto; Parameter Description proto Protocol number Description: This call searches the ETC\PROTOCOL file for the specified protocol number. Return Value: The getprotobynumber() call returns a pointer to a protoent structure for the network protocol specified on the call. The return value points to static data that subsequent API calls can modify. A pointer to a protoent structure indicates success. A NULL pointer indicates an error or EOF. The protoent structure is defined in the header file and contains the following elements: Element Description p_name Official name of the protocol p_aliases Array, terminated with a NULL pointer, of alternative names for the protocol p_proto Protocol number ═══ 7.18. getprotoent() ═══ Returns a pointer to the next entry in the PROTOCOL file. #include struct protoent *getprotoent() Description: This call searches for the next entry in the ETC\PROTOCOL file. Return Value: The getprotoent() call returns a pointer to the next entry in the file, ETC\PROTOCOL. The return value points to static data that subsequent API calls can modify. A pointer to a protoent structure indicates success. A NULL pointer indicates an error or EOF. The protoent structure is defined in the header file and contains the following elements: Element Description p_name Official name of the protocol p_aliases Array, terminated with a NULL pointer, of alternative names for the protocol p_proto Protocol number ═══ 7.19. getservbyname() ═══ Returns a pointer to the SERVICES file entry specified by a service name. #include struct servent *getservbyname(name, proto) char *name; char *proto; Parameter Description name Pointer to the service name proto Pointer to the specified protocol Description: This call searches the ETC\SERVICES file for the specified service name, which must match the protocol if a protocol is stated. Return Value: The call returns a pointer to a servent structure for the network service specified on the call. The return value points to static data that subsequent API calls can modify. A pointer to a servent structure indicates success. A NULL pointer indicates an error or EOF. The servent structure is defined in the header file and contains the following elements: Element Description s_name Official name of the service s_aliases Array, terminated with a NULL pointer, of alternative names for the service s_port Port number of the service s_proto Required protocol to contact the service ═══ 7.20. getservbyport() ═══ Returns a pointer to the SERVICES file entry specified by a port number. #include struct servent *getservbyport(port, proto) int port; char *proto; Parameter Description port Specified port proto Pointer to the specified protocol Description: This call sequentially searches the ETC\SERVICES file for the specified port number, which must match the protocol if a protocol is stated. Return Value: The getservbyport() call returns a pointer to a servent structure for the port number specified on the call. The return value points to static data that subsequent API calls can modify. A pointer to a servent structure indicates success. A NULL pointer indicates an error or EOF. The servent structure is defined in the header file and contains the following elements: Element Description s_name Official name of the service s_aliases Array, terminated with a NULL pointer, of alternative names for the service s_port Port number of the service s_proto Required protocol to contact the service ═══ 7.21. getservent() ═══ Returns a pointer to the next entry in the SERVICES file. #include struct servent *getservent() Description: This call searches for the next line in the ETC\SERVICES file. Return Value: The getservent() call returns a pointer to the next entry in the ETC\SERVICES file. The return value points to static data that subsequent API calls can modify. A pointer to a servent structure indicates success. A NULL pointer indicates an error or EOF. The servent structure is defined in the header file and contains the following elements: Element Description s_name Official name of the service s_aliases Array, terminated with a NULL pointer, of alternative names for the service s_port Port number of the service s_proto Required protocol to contact the service ═══ 7.22. htonl() ═══ Translates a long integer from host-byte order to network-byte order. #include #include u_long htonl(a) u_long a; Parameter Description a Unsigned long integer to be put into network-byte order Description: This call translates a long integer from host-byte order to network-byte order. Return Value: Returns the translated long integer. ═══ 7.23. htons() ═══ Translates a short integer from host-byte order to network-byte order. #include #include u_short htons(a) u_short a; Parameter Description a Unsigned short integer to be put into network-byte order Description: This call translates a short integer from host-byte order to network-byte order. Return Value: Returns the translated short integer. ═══ 7.24. inet_addr() ═══ Constructs an internet address from character strings representing numbers expressed in standard dotted-decimal notation. #include u_long inet_addr(cp) char *cp; Parameter Description cp A character string in standard dotted-decimal notation Description: This call interprets character strings representing numbers expressed in standard dotted-decimal notation and returns numbers suitable for use as an internet address. Values specified in standard dotted-decimal notation take one of the following forms: a.b.c.d a.b.c a.b a When a four-part address is specified, each part is interpreted as a byte of data and assigned, from left to right, to one of the 4 bytes of an internet address. When a three-part address is specified, the last part is interpreted as a 16-bit quantity and placed in the two rightmost bytes of the network address. This makes the three-part address format convenient for specifying Class B network addresses as 128.net.host. When a two-part address is specified, the last part is interpreted as a 24-bit quantity and placed in the three rightmost bytes of the network address. This makes the two-part address format convenient for specifying Class A network addresses as net.host. When a one-part address is specified, the value is stored directly in the network address space without any rearrangement of its bytes. Numbers supplied as address parts in standard dotted-decimal notation can be decimal, hexadecimal, or octal. Numbers are interpreted in C language syntax. A leading 0x implies hexadecimal; a leading 0 implies octal. A number without a leading 0 implies decimal. Return Value: The internet address is returned in network-byte order. ═══ 7.25. inet_lnaof() ═══ Returns the local network portion of an internet address. #include #include u_long inet_lnaof(in) struct in_addr in; Parameter Description in Host internet address Description: This call breaks apart the internet host address and returns the local network address portion. Return Value: The local network address is returned in host-byte order. ═══ 7.26. inet_makeaddr() ═══ Constructs an internet address from a network number and a local address. #include #include struct in_addr inet_makeaddr(net, lna) u_long net; u_long lna; Parameter Description net Network number lna Local network address Description: This call takes a network number and a local network address and constructs an internet address. Return Value: The internet address is returned in network-byte order. ═══ 7.27. inet_netof() ═══ Returns the network portion of the internet host address in network-byte order. #include #include u_long inet_netof(in) struct in_addr in; Parameter Description in Internet address in network-byte order Description: This call breaks apart the internet host address and returns the network number portion. Return Value: The network number is returned in host-byte order. ═══ 7.28. inet_network() ═══ Constructs a network number from character strings representing numbers expressed in standard dotted-decimal notation. #include u_long inet_network(cp) char *cp; Parameter Description cp A character string in standard dotted-decimal notation Description: This call interprets character strings representing numbers expressed in standard dotted-decimal notation and returns numbers suitable for use as a network number. Return Value: The network number is returned in host-byte order. ═══ 7.29. inet_ntoa() ═══ Returns a pointer to a string in dotted-decimal notation. #include #include char *inet_ntoa(in) struct in_addr in; Parameter Description in Host internet address Description: This call returns a pointer to a string expressed in the dotted-decimal notation. The inet_ntoa() call accepts an internet address expressed as a 32-bit quantity in network-byte order and returns a string expressed in dotted-decimal notation. Return Value: Returns a pointer to the internet address expressed in dotted-decimal notation. ═══ 7.30. lswap() ═══ Swaps bytes in a long integer. #include #include u_long lswap(a) u_long a; Parameter Description a Unsigned long integer whose bytes are to be swapped Description: This call swaps bytes in a long integer. Return Value: Returns the translated long integer. ═══ 7.31. ntohl() ═══ Translates a long integer from network-byte order to host-byte order. #include #include u_long ntohl(a) u_long a; Parameter Description a Unsigned long integer to be put into host-byte order Description: This call translates a long integer from network-byte order to host-byte order. Return Value: Returns the translated long integer. ═══ 7.32. ntohs() ═══ Translates a short integer from network-byte order to host-byte order. #include #include u_short ntohs(a) u_short a; Parameter Description a Unsigned short integer to be put into host-byte order Description: This call translates a short integer from network-byte order to host-byte order. Return Value: The ntohs() call returns the translated short integer. ═══ 7.33. res_init() ═══ Reads the RESOLV file for the default domain name. #include #include #include #include void res_init() Description: This call reads the ETC\RESOLV file for the default domain name and for the internet address of the initial hosts running the name server. If that file does not exist, the call attempts name resolution using the ETC\HOSTS file. One of these files should be operational. The call stores domain name information in the global _res structure, which is defined in the header file. ═══ 7.34. res_mkquery() ═══ Makes a query message for the name servers in the internet domain. #include #include #include #include int res_mkquery (op, dname, class, type, data, datalen, newrr, buf, buflen) int op; char *dname; int class; int type; char *data; int datalen; struct rrec *newrr; char *buf; int buflen; Parameter Description op The usual type is QUERY, but you can set the parameter to any query type defined in the header file. dname Pointer to the domain name. If dname points to a single label and the RES_DEFNAMES bit in the _res structure defined in the header file is set, the call appends dname to the current domain name. The current domain name is defined in the ETC\RESOLV file. class One of the following values: C_IN ARPA internet C_CHAOS Chaos network at MIT type One of the following type values for resources and queries: T_A Host address T_NS Authoritative server T_MD Mail destination T_MF Mail forwarder T_CNAME Canonical name T_SOA Start of authority zone T_MB Mailbox domain name T_MG Mail group member T_MR Mail rename name T_NULL NULL resource record T_WKS Well-known service T_PTR Domain name pointer T_HINFO Host information T_MINFO Mailbox information T_MX Mail routing information T_UINFO User information T_UID User ID T_GID Group ID data Pointer to the data sent to the name server as a search key datalen Size of the data parameter in bytes newrr Reserved. Unused parameter. buf Pointer to the query message buflen Length of the buffer in bytes pointed to by the buf parameter Description: This call makes a query message for the name servers in the internet domain and puts that query message in the location pointed by the buf parameter. It uses global _res structure, which is defined in the header file. Return Value: If it succeeds, the res_mkquery() call returns the size of the query. If the query is larger than the value of buflen, the call fails and returns a value of -1. ═══ 7.35. res_send() ═══ Sends a query to a local name server. #include #include #include #include int re_send(msg, msglen, ans, anslen) char *msg; int msglen; char *ans; int anslen; Parameter Description msg Pointer to the beginning of a message msglen Length of the buffer in bytes pointed to by the msg parameter ans Pointer to the location where the received response is stored anslen Length of the buffer in bytes pointed by the ans parameter Description: This call sends a query to the local name server and calls the res_init() call if the RES_INIT option of the global _res structure is not set. It also handles timeouts and retries. It uses the global _res structure, which is defined in the header file. Return Value: If it succeeds, the call returns the length of the message. If it fails, the call returns a value of -1. ═══ 7.36. sethostent() ═══ Opens and rewinds the HOSTS file. #include void sethostent(stayopen) int stayopen; Parameter Description stayopen Allows the ETC\HOSTS file to stay open after each call Description: This call opens and rewinds the ETC\HOSTS file. If the stayopen parameter is nonzero, the ETC\HOSTS file stays open after each of the gethost calls. Return Value: The sethostent() call returns a global pointer to the FILE structure defined in the header file. A NULL pointer indicates an error or EOF. ═══ 7.37. setnetent() ═══ Opens and rewinds the NETWORKS file. #include void setnetent(stayopen) int stayopen; Parameter Description stayopen Allows the ETC\NETWORKS file to stay open after each call Description: This call opens and rewinds the ETC\NETWORKS file, which contains information about known networks. If the stayopen parameter is nonzero, the ETC\NETWORKS file stays open after each of the getnet calls. Return Value: The setnetent() call returns a global pointer to the FILE structure defined in the header file. A NULL pointer indicates an error or EOF. ═══ 7.38. setprotoent() ═══ Opens and rewinds the PROTOCOL file. #include void setprotoent(stayopen) int stayopen; Parameter Description stayopen Allows the ETC\PROTOCOL file to stay open after each call Description: This call opens and rewinds the ETC\PROTOCOL file, which contains information about known protocols. If the stayopen parameter is nonzero, the ETC\PROTOCOL file stays open after each of the getproto calls. Return Value: The setprotoent() call returns a global pointer to the FILE structure defined in the header file. A NULL pointer indicates an error or EOF. ═══ 7.39. setservent() ═══ Opens and rewinds the SERVICES file. #include void setservent(stayopen) int stayopen; Parameter Description stayopen Allows the ETC\SERVICES file to stay open after each call Description: This call opens and rewinds the ETC\SERVICES file, which contains information about known services and well-known ports. If the stayopen parameter is nonzero, the ETC\SERVICES file stays open after each of the getserv calls. Return Value: The setservent() call returns a global pointer to the FILE structure defined in the header file. A NULL pointer indicates an error or EOF. ═══ 8. Socket Error Return Code Constants ═══ The following table provides the error constants set by socket calls. This table can be found in the header file. For further system error return code numbers, refer to the compiler header file. You can use the psock_errno() call to write short error messages to the standard error device. Refer to psock_errno() for additional information. #define SOCBASEERR 0 /* * SOCKET API definitions of error constants */ #define SOCEPERM 1 /* Not owner */ #define SOCESRCH 3 /* No such process */ #define SOCEINTR 4 /* Interrupted system call */ #define SOCENXIO 6 /* No such device or address */ #define SOCEBADF 9 /* Bad file number */ #define SOCEACCES 13 /* Permission denied */ #define SOCEFAULT 14 /* Bad address */ #define SOCEINVAL 22 /* Invalid argument */ #define SOCEMFILE 24 /* Too many open files */ #define SOCEPIPE 32 /* Broken pipe */ #define SOCEOS2ERR 100 /* OS/2 Error */ /* * Networking-related BSD errno values. */ #define EWOULDBLOCK 35 /* Operation would block */ #define EINPROGRESS 36 /* Operation now in progress */ #define EALREADY 37 /* Operation already in progress */ #define ENOTSOCK 38 /* Socket operation on nonsocket */ #define EDESTADDRREQ 39 /* Destination address required */ #define EMSGSIZE 40 /* Message too long */ #define EPROTOTYPE 41 /* Protocol wrong type for socket */ #define ENOPROTOOPT 42 /* Protocol not available */ #define EPROTONOSUPPORT 43 /* Protocol not supported */ #define ESOCKTNOSUPPORT 44 /* Socket type not supported */ #define EOPNOTSUPP 45 /* Operation not supported on socket */ #define EPFNOSUPPORT 46 /* Protocol family not supported */ #define EAFNOSUPPORT 47 /* Address family not supported by protocol family * / #define EADDRINUSE 48 /* Address already in use */ #define EADDRNOTAVAIL 49 /* Cannot assign requested address */ #define ENETDOWN 50 /* Network is down */ #define ENETUNREACH 51 /* Network is unreachable */ #define ENETRESET 52 /* Network dropped connection on reset */ #define ECONNABORTED 53 /* Software caused connection to stop */ #define ECONNRESET 54 /* Connection reset by peer */ #define ENOBUFS 55 /* No buffer space available */ #define EISCONN 56 /* Socket is already connected */ #define ENOTCONN 57 /* Socket is not connected */ #define ESHUTDOWN 58 /* Cannot send after socket shutdown */ #define ETOOMANYREFS 59 /* Too many references: cannot splice */ #define ETIMEDOUT 60 /* Connection timed out */ #define ECONNREFUSED 61 /* Connection refused */ #define ELOOP 62 /* Too many levels of symbolic links */ #define ENAMETOOLONG 63 /* File name too long */ #define EHOSTDOWN 64 /* Host is down */ #define EHOSTUNREACH 65 /* No route to host */ #define ENOTEMPTY 66 /* Directory not empty */ /* * OS/2 SOCKET API definitions of regular BSD error constants */ #define SOCEWOULDBLOCK EWOULDBLOCK #define SOCEINPROGRESS EINPROGRESS #define SOCEALREADY EALREADY #define SOCENOTSOCK ENOTSOCK #define SOCEDESTADDRREQ EDESTADDRREQ #define SOCEMSGSIZE EMSGSIZE #define SOCEPROTOTYPE EPROTOTYPE #define SOCENOPROTOOPT ENOPROTOOPT #define SOCEPROTONOSUPPORT EPROTONOSUPPORT #define SOCESOCKTNOSUPPORT ESOCKTNOSUPPORT #define SOCEOPNOTSUPP EOPNOTSUPP #define SOCEPFNOSUPPORT EPFNOSUPPORT #define SOCEAFNOSUPPORT EAFNOSUPPORT #define SOCEADDRINUSE EADDRINUSE #define SOCEADDRNOTAVAIL EADDRNOTAVAIL #define SOCENETDOWN ENETDOWN #define SOCENETUNREACH ENETUNREACH #define SOCENETRESET ENETRESET #define SOCECONNABORTED ECONNABORTED #define SOCECONNRESET ECONNRESET #define SOCENOBUFS ENOBUFS #define SOCEISCONN EISCONN #define SOCENOTCONN ENOTCONN #define SOCESHUTDOWN ESHUTDOWN #define SOCETOOMANYREFS ETOOMANYREFS #define SOCETIMEDOUT ETIMEDOUT #define SOCECONNREFUSED ECONNREFUSED #define SOCELOOP ELOOP #define SOCENAMETOOLONG ENAMETOOLONG #define SOCEHOSTDOWN EHOSTDOWN #define SOCEHOSTUNREACH EHOSTUNREACH #define SOCENOTEMPTY ENOTEMPTY ═══ 9. Well-Known Port Assignments ═══ The following table is a list of the well-known ports supported by TCP/IP. It provides the port number, keyword, and a description of the reserved port assignment. Port numbers of less than 1024 are reserved for system applications. You can also find a list of some of these well-known port numbers in the ETC\SERVICES file. TCP Well-Known Port Assignments ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 21. TCP Well-Known Port Assignments │ ├─────────┬───────────┬───────────────────────────┬───────────────────────────┤ │ PORT │ │ │ │ │ NUMBER │ KEYWORD │ RESERVED FOR │ SERVICES DESCRIPTION │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 0 │ │ reserved │ │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 5 │ RJE │ remote job entry │ remote job entry │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 7 │ ECHO │ echo │ echo │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 9 │ DISCARD │ discard │ sink null │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 11 │ SYSTAT │ active users │ active users │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 13 │ DAYTIME │ daytime │ daytime │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 15 │ NETSTAT │ Netstat │ who is up or Netstat │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 19 │ CHARGEN │ ttytst source │ character generator │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 21 │ FTP │ FTP │ File Transfer Protocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 23 │ TELNET │ Telnet │ Telnet │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 25 │ SMTP │ mail │ Simple Mail Transfer Pro- │ │ │ │ │ tocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 37 │ TIME │ timeserver │ timeserver │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 39 │ RLP │ resource │ Resource Location Pro- │ │ │ │ │ tocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 42 │ NAMESERVER│ name │ host name server │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 43 │ NICNAME │ who is │ who is │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 53 │ DOMAIN │ name server │ domain name server │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 57 │ MTP │ private terminal access │ private terminal access │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 69 │ TFTP │ TFTP │ Trivial File Transfer │ │ │ │ │ Protocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 77 │ │ netrjs │ any private RJE service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 79 │ FINGER │ finger │ finger │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 87 │ LINK │ ttylink │ any private terminal link │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 95 │ SUPDUP │ supdup │ SUPDUP Protocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 101 │ HOSTNAME │ hostname │ nic hostname server, │ │ │ │ │ usually from SRI-NIC │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 109 │ POP │ postoffice │ Post Office Protocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 111 │ SUNRPC │ sunrpc │ Sun remote procedure call │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 113 │ AUTH │ authentication │ authentication service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 115 │ SFTP │ sftp │ Simple File Transfer Pro- │ │ │ │ │ tocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 117 │ UUCP-PATH │ UUCP path service │ UUCP path service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 119 │ UNTP │ readnews untp │ USENET News Transfer Pro- │ │ │ │ │ tocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 123 │ NTP │ NTP │ Network Time Protocol │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 160 │ │ reserved │ │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 161 │ SNMP │ SNMP Agent │ SNMP Agent receives │ │ │ │ │ packets │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 162 │ SNMPTRAP │ SNMP Client │ SNMP Client receives SNMP │ │ │ │ │ TRAPs │ └─────────┴───────────┴───────────────────────────┴───────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 21. TCP Well-Known Port Assignments │ ├─────────┬───────────┬───────────────────────────┬───────────────────────────┤ │ PORT │ │ │ │ │ NUMBER │ KEYWORD │ RESERVED FOR │ SERVICES DESCRIPTION │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 163-223 │ │ reserved │ │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 449 │ AS-SVRMAP │ mapper function for │ servers for signon, │ │ │ │ AS/400 servers │ central management, │ │ │ │ │ network print, database, │ │ │ │ │ stream file, data queue, │ │ │ │ │ and remote command and │ │ │ │ │ distributed program │ │ │ │ │ calls. │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 712 │ VEXEC │ vice-exec │ Andrew File System │ │ │ │ │ authenticated service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 713 │ VLOGIN │ vice-login │ Andrew File System │ │ │ │ │ authenticated service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 714 │ VSHELL │ vice-shell │ Andrew File System │ │ │ │ │ authenticated service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 2001 │ FILESRV │ │ Andrew File System │ │ │ │ │ service │ ├─────────┼───────────┼───────────────────────────┼───────────────────────────┤ │ 2106 │ VENUS.ITC │ │ Andrew File System │ │ │ │ │ service, for the Venus │ │ │ │ │ process │ └─────────┴───────────┴───────────────────────────┴───────────────────────────┘ UDP Well-Known Port Assignments ┌─────────────────────────────────────────────────────────────────────────────┐ │ Table 22. UDP Well-Known Port Assignments │ ├───────────┬───────────┬────────────────────┬────────────────────────────────┤ │ PORT │ │ │ │ │ NUMBER │ KEYWORD │ RESERVED FOR │ SERVICES DESCRIPTION │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 0 │ │ reserved │ │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 5 │ RJE │ remote job entry │ remote job entry │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 7 │ ECHO │ echo │ echo │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 9 │ DISCARD │ discard │ sink null │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 11 │ USERS │ active users │ active users │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 13 │ DAYTIME │ daytime │ daytime │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 15 │ NETSTAT │ Netstat │ Netstat │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 19 │ CHARGEN │ ttytst source │ character generator │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 37 │ TIME │ timeserver │ timeserver │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 39 │ RLP │ resource │ Resource Location Protocol │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 42 │ NAMESERVER│ name │ host name server │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 43 │ NICNAME │ who is │ who is │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 53 │ DOMAIN │ name server │ domain name server │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 67 │ BOOTPS │ bootps │ bootp server │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 68 │ BOOTPC │ bootpc │ bootp client │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 69 │ TFTP │ TFTP │ Trivial File Transfer Protocol │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 75 │ │ │ any private dial out service │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 77 │ │ netrjs │ any private RJE service │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 79 │ FINGER │ finger │ finger │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 111 │ SUNRPC │ sunrpc │ Sun remote procedure call │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 123 │ NTP │ NTP │ Network Time Protocol │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 135 │ LLBD │ NCS LLBD │ NCS local location broker │ │ │ │ │ daemon │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 160-223 │ │ reserved │ │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 531 │ RVD-CONTRO│ │ rvd control port │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2001 │ RAUTH2 │ │ Andrew File System service, │ │ │ │ │ for the Venus process │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2002 │ RFILEBULK │ │ Andrew File System service, │ │ │ │ │ for the Venus process │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2003 │ RFILESRV │ │ Andrew File System service, │ │ │ │ │ for the Venus process │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2018 │ CONSOLE │ │ Andrew File System service │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2115 │ ROPCONS │ │ Andrew File System service, │ │ │ │ │ for the Venus process │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2131 │ RUPDSRV │ │ assigned in pairs; bulk must │ │ │ │ │ be SRV +1 │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2132 │ RUPDBULK │ │ assigned in pairs; bulk must │ │ │ │ │ be SRV +1 │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2133 │ RUPDSRV1 │ │ assigned in pairs; bulk must │ │ │ │ │ be SRV +1 │ ├───────────┼───────────┼────────────────────┼────────────────────────────────┤ │ 2134 │ RUPDBULK1 │ │ assigned in pairs; bulk must │ │ │ │ │ be SRV +1 │ └───────────┴───────────┴────────────────────┴────────────────────────────────┘ ═══ 10. Notices ═══ First Edition (June, 1996) The following paragraph does not apply to the United Kingdom or any country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This publication could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time. It is possible that this publication may contain reference to, or information about, IBM products (machines and programs), programming, or services that are not announced in your country. Such references or information must not be construed to mean that IBM intends to announce such IBM products, programming, or services in your country. Requests for technical information about IBM products should be made to your IBM authorized reseller or IBM marketing representative. ═══ 10.1. Copyright Notices ═══ COPYRIGHT LICENSE: This publication contains printed sample application programs in source language, which illustrate OS/2 programming techniques. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the OS/2 application programming interface. Each copy of any portion of these sample programs or any derivative work, which is distributed to others, must include a copyright notice as follows: "(C) (your company name) (year). All rights reserved." (C)Copyright International Business Machines Corporation 1993, 1996. All rights reserved. Note to U.S. Government Users - Documentation related to restricted rights - Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp. ═══ 10.2. Disclaimers ═══ References in this publication to IBM products, programs, or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any of IBM's intellectual property rights or other legally protectable rights may be used instead of the IBM product, program, or service. Evaluation and verification of operation in conjunction with other products, programs, or services, except those expressly designated by IBM, are the user's responsibility. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood NY 10594, U.S.A. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Department RM1A, 1000 N.W. 51st Street, Boca Raton, FL 33431, U.S.A. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.