#include <sys/types.h> #include <sys/socket.h> int accept(int s, void *addr, int *addrlen);
accept
extracts the first connection in the queue of
connection requests, creates a new socket with the same properties as
socket descriptor s
, and allocates a new socket descriptor
for the socket. Connection-based servers use accept
to create a connection that is requested by a client.
Socket s
is a connection-based socket of type
SOCK_STREAM
that is bound to an address with a bind
call
and
listens for connections with a listen
call.
If there are no
pending connection requests and
ioctl
or fcntl
has not been used to designate the
socket as non-blocking, accept
blocks the caller
until there
is a connection. If the socket is designated as non-blocking, and
there are no pending connection requests, accept
returns a -1 and sets errno
to EWOULDBLOCK
; the new
socket descriptor cannot be used
to accept more connections. Socket descriptor s
remains
open.
addr
and addrlen
describe the buffer into which
accept
places the address of the new peer. addr
can be NULL
.
If it is not NULL
, it should point to a sockaddr
structure or one
of its derivatives, such as sockaddr_in
.
addrlen
points to an integer containing the size of the buffer in bytes. If
the buffer size is not large enough to contain the address of the
peer, the value of the address is not completely copied. No error
occurs in this situation. On return, the integer pointed to by
addrlen
is set to
the length that was
actually copied.
If socket s
is a member of the read
descriptor set (readfds
), you can use a select
call to
discover whether or not any connections are pending.
accept
is successful, it returns a nonnegative value that
is the descriptor of the newly created socket.
Otherwise, it returns a -1
.
accept
is portable to other environments, including
UNIX systems, that implement BSD
sockets.
accept
is used to accept
incoming connection requests.
/* This is a complete example of a simple server for the */ /* daytime protocol. A daytime server waits on port */ /* 13 and returns a human readable date and time string */ /* whenever any client requests a connection. */ /* This server handles only TCP. The client does not need */ /* to write to the server. The server responds with */ /* the date and time as soon as the connection is made. */ /* We will implement an iterative server (one which handles */ /* connections one at a time) instead of a concurrent */ /* server (one which handles several connections */ /* simultaneously). */ /* This program runs until it is stopped by an operating */ /* system command. */ #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <time.h> /* No need to translate characters on ASCII systems. */ #ifndef __SASC__ #define ntohcs(c) (c) #define htoncs(c) (c) #endif /* Define some useful constants. */ #define TRUE 1 #define DAYTIME_PORT 13 main() { /* Socket descriptors. "s" will be the model descriptor */ /* that indicates the type of connections that we */ /* want to accept. "cs" will be the socket used for */ /* communications with clients. */ int s, cs; /* socket addresses for server and client */ struct sockaddr_in sa_serv; struct sockaddr_in sa_clnt; int sa_len; /* will contain information about the daytime service */ struct servent *serv; /* variables used to obtain the time */ char *p; int len; time_t t; /* buffer for outgoing time string */ char outbuf[128]; /* Get a socket of the proper type. We use SOCK_STREAM */ /* because we want to communicate using TCP. */ s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("daytime - socket() failed"); exit(EXIT_FAILURE); } /* Find the port for the daytime service. If the */ /* services file is not available, we will use the */ /* standard number. We specify "tcp" as the protocol. */ /* This call will attempt to find the services file. */ serv = getservbyname("daytime", "tcp"); /* Prepare a socket address for the server. We specify */ /* INADDR_ANY instead of an IP address because we */ /* want to accept connections over any IP address */ /* by which this host is known. We specify the */ /* well-known port number for the daytime server if */ /* the program is compiled for a PRIVILEGED user */ /* (root on UNIX). Otherwise, we let TCP/IP select */ /* the port and then we print it so that clients will */ /* know what port to ask for. */ memset(&sa_serv,'\0',sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; #ifdef PRIVILEGED sa_serv.sin_port = serv ? serv->s_port : htons(DAYTIME_PORT); #else sa_serv.sin_port = 0; #endif /* Bind our socket to the desired address. Now clients */ /* specifying this address will reach this server. */ if (bind(s, &sa_serv, sizeof(sa_serv)) == -1) { perror("daytime - bind() failed"); return(EXIT_FAILURE); } #ifndef PRIVILEGED sa_len = sizeof(sa_serv); if (getsockname(s, &sa_serv, &sa_len) == -1) { perror("daytime - getsockname() failed"); return(EXIT_FAILURE); } printf("Daytime server port is: %d\n", (int) ntohs(sa_serv.sin_port)); #endif /* Set up a queue for incoming connection requests. */ listen(s, SOMAXCONN); /* Accept incoming requests until cancelled by the */ /* operating system or an error occurs. */ while (TRUE) { /* Accept a new request. Ask for client's address */ /* so that we can print it if there is an error. */ sa_len = sizeof(sa_clnt); cs = accept(s, &sa_clnt, &sa_len); if (cs==-1) { perror("daytime - accept() failed"); return EXIT_FAILURE; } /* Send the time to the client. Daytime clients */ /* expect the string to be in ASCII. */ time(&t); /* machine-readable time */ p = ctime(&t); /* human-readable time */ /* Convert to ASCII if necessary. */ for (len=0; p[len] && len<sizeof(outbuf); len++) outbuf[len] = htoncs(p[len] ); if (write(cs,outbuf,len)==-1) { perror("daytime - write() failed"); printf("Client IP address: %s\n", inet_ntoa(sa_clnt.sin_addr)); return EXIT_FAILURE; } close(cs); } return EXIT_SUCCESS; /* Avoid compilation warnings. */ }
bind
,
connect
,
listen
,
select
,
socket
#include <sys/types.h> #include <sys/socket.h> int bind(int s, const void *addr, int addrlen);
bind
assigns a name to an unnamed socket s
.
When a socket is
created, it exists in an address family, but it does not have a name
assigned to it. Servers use bind
to associate themselves with
a well-known port. Servers may also use bind
to
restrict
access by other network addresses on a host with multiple network
addresses. bind
enables a connectionless client to have an
address that the server can use for responses.
For addresses in the AF_INET
family, addr
points to
a sockaddr
or sockaddr_in
structure.
addrlen
is the length of
the address, in bytes. addrlen
should be greater than or
equal to the size of the sockaddr
or sockaddr_in
structure. The INADDR_ANY
constant in the
<netinet/in.h>
header file specifies that the network address
is not restricted. If the sin_port
field of the
sockaddr
structure is zero,
bind
chooses a port. Alternatively, a well-known port number
can be passed in the sin_port
field. Internet host
addresses and port numbers in sockaddr_in
are always in
network byte order. The remainder of the sockaddr
or
sockaddr_in
structure should be 0
.
If successful, the sin_port
value may be obtained
by calling getsockname
. getsockname
will store the assigned address and port into the sockaddr
structure.
On return, the structure pointed to by addr
should
be the same as the structure pointed to by getsockname
for
this socket s
.
bind
is successful, it returns a 0
; otherwise, it
returns a -1
and sets errno
to indicate the type of error.
bind
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
bind
assigns socket
s
to an arbitrary port without restriction by
network address.
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #include <stdio.h> f() { struct sockaddr_in sa; int s; struct servent *serv; . . . /* Specify the port. */ memset(&sa,'\0',sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = serv->s_port; if (bind(s, &sa, sizeof(sa)) == -1) { perror("bind() failed"); return -1; } . . . /* Let TCP/IP choose the port. */ memset(&sa,'\0',sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; if (bind(s, &sa, sizeof(sa)) == -1) { perror("bind() failed"); return -1; } . . . }
connect
,
getservbyname
,
getsockname,
htons
#include <sys/types.h> #include <sys/socket.h> int connect(int s, const void *addr, int addrlen);
connect
attempts to associate socket s
with a
peer process at address addr
.
addr
is a pointer to a buffer containing the
address of the peer socket. addrlen
is the length, in
bytes, of the buffer pointed to by addr
. addrlen
should be greater than or equal to the number of bytes in the
sockaddr
or sockaddr_in
structure.
For connection-oriented protocols on blocking sockets, when the
establishment of a
connection is actually attempted, the call blocks I/O until the
connection attempt succeeds or fails. On non-blocking sockets, the
call
returns immediately, with errno
set to EINPROGRESS
if the
connection could not complete immediately. The caller can then
discover whether or not the connection is complete by
issuing
the select
call to determine if the socket is ready for
writing.
For sockets that use connectionless protocols, connect
enables
the socket to register a destination address once, instead of having
to specify the same destination address for every read or write
operation. By associating a packet with a specific
socket, connect
provides more information with which
to trace the source of the problem if a transmission fails.
In this case, connect
can be called many times.
connect
is successful, it returns a 0
; otherwise, it
returns a -1
and sets errno
to indicate the type of error.
If errno
is set to ECONNREFUSED
, reuse of the
failed socket descriptor is
TCP/IP implementation-specific and unpredictable. However, it
is always safe to close and obtain another socket descriptor for
subsequent calls to connect
.
connect
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
connect
connects socket s
to a specific host and port.
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <string.h> f() { struct sockaddr_in sa; struct hostent *host; struct servent *serv; int s; . . . /* Specify destination socket address (IP address and */ /* port number). */ memset(&sa,'\0',sizeof(sa)); sa.sin_family = AF_INET; memcpy(&sa.sin_addr,host->h_addr,sizeof(sa.sin_addr)); sa.sin_port = serv->s_port; /* Connect to the host and port. */ if (connect(s, &sa, sizeof(sa)) == -1) { perror("connect() failed"); return -1; } . . . }
accept
,
select
,
socket
,
getpeername
#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> int dn_comp(char *exp_dn, char *comp_dn, int length, char **dnptrs, char **lastdnptr);
dn_comp
is part of the
resolver, which is a set of routines that provides a
programming interface for communicating with Internet name servers.
dn_comp
translates domain names in conventional character
string format to the compressed format used by name servers. The
compression process merges common suffixes among the names included in
a name server query.
exp_dn
is an EBCDIC
string that contains a DNS name, such as a host name.
dn_comp
stores the equivalent compressed string in the buffer pointed to by
comp_dn
. length
is the size of this buffer in bytes.
dn_comp
also maintains a list of compressed name elements.
This list is used as a reference to eliminate common suffixes
during a series of calls to dn_comp
when multiple names are
stored in the same buffer.
dnptrs
points to the beginning of an array of pointers
that points to the
list of compressed name elements. The calling program allocates this
array by using a convenient size, such as 10 elements.
lastdnptr
points to the last element of the array.
dnptrs[0]
should point to the beginning of the message.
Initially, dnptrs[1]
should be NULL
.
In the interests of greater portability, the
SAS/C version of dn_comp
performs EBCDIC-to-ASCII
translation of exp_dn
before beginning its compression
process.
If dnptr
is NULL
, the domain name
is not compressed. Alternatively, if lastdnptr
is NULL
, the
list of labels is
not updated.
For information on the UNIX programming interface and Internet name servers, refer to "The Domain Name System" and "The Socket Interface" in Internetworking with TCP/IP, Volume I.
dn_comp
is successful, it returns the size of the compressed
domain name. Otherwise, it returns a -1
and sets errno
to indicate the type of error.
dn_comp
is available on most
versions of the UNIX operating system.
dn_comp
is a direct port from the BSD
UNIX socket library. The EBCDIC-to-ASCII translation feature is the
only
change.
dn_expand
,
res_mkquery
#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> int dn_expand(char *msg, char *eomorig, char *comp_dn, char *exp_dn, int length);
dn_expand
expands the compressed domain name
to a full domain
name. Expanded names are converted to uppercase EBCDIC.
msg
eonmorig
comp_dn
exp_dn
length
that receives the expanded domain name.
dn_expand
is part of the
resolver. The resolver is a set of routines that provide a
programming interface for communicating with Internet name servers.
dn_expand
translates domain names from the compressed
format used by name servers to conventional character
string format. In the interests
of greater portability, the SAS/C version of dn_expand
performs ASCII-to-EBCDIC translation of exp_dn
.
For information on the UNIX programming interface and Internet name servers, refer to "The Domain Name System" and "The Socket Interface" in Internetworking with TCP/IP, Volume I.
dn_expand
returns the size of the compressed
domain
name. Otherwise, it returns a -1
, and sets errno
to
indicate the type of error.
dn_expand
is available on most
versions of the UNIX operating system.
dn_expand
is a direct port from the
BSD
UNIX Socket Library. The ASCII-to-EBCDIC translation feature is the
only
change.
dn_comp
,
res_mkquery
#include <netdb.h> void endhostent(void);
endhostent
closes a
host file or TCP connection. endhostent
is a combination of
the
host file and resolver versions of the BSD UNIX Socket
Library endhostent
.
In some instances, when the resolver is used to look up the host name,
a
virtual
circuit (that is, a TCP connection) is used to communicate with the
name server, based on the RESOLVEVIA
statement in the
TCPIP.DATA file
or the RES_USEVC
resolver option specified by your program. In
these cases, you can use the RES_STAYOPEN
resolver option to maintain the
connection with the name server between queries. endhostent
closes this connection. (See Bitwise OR Options for
information about RES_USEVC
and RES_STAYOPEN
.)
In other instances, the host file is used as a source of host
names. If the host file is opened with a sethostent
call
and the stayopen
parameter is a nonzero value, endhostent
closes the host file.
Refer to Network Administration for information on naming host files and the logic that determines whether the host file or the resolver is used for looking up names.
endhostent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
endhostent
is a combination of the
host file and resolver versions of the BSD UNIX Socket
Library gethostbyaddr
.
sethostent
,
gethostent
,
gethostbyname
#include <netdb.h> void endnetent(void);
endnetent
closes the
network file, that is, a file with the same format as /etc/networks
in the UNIX environment. Refer to Network Administration
for
information on naming this file for your system.
endnetent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getnetbyaddr
,
getnetbyname
,
getnetent
,
setnetent
#include <netdb.h> void endprotoent(void);
endprotoent
closes the
protocol file, that is, a file with the same format as /etc/protocols
in the UNIX environment. Refer to Network Administration
for
information on naming this file for your system.
endprotoent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getprotobynumber
,
getprotobyname
,
getprotoent
,
setprotoent
/etc/rpc
Protocol File#include <netdb.h> int endrpcent(void);
endrpcent
closes the protocol file, that is, a file with the same
format as /etc/rpc
in the UNIX environment. Refer to
Chapter 17, "Network Administration" for information on naming this
file for your system.
getrpcent
is portable to other systems that support Sun RPC 4.0.
getrpcbyname
, getrpcbynumber
, getrpcent
, setrpcent
#include <netdb.h> void endservent(void);
endservent
closes the
services file, that is, a file with the same format as /etc/services
in the UNIX environment. Refer to Network Administration
for
information on naming this file for your system.
endservent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getservent
,
setservent
,
getservbyname
,
getservbyport
#include <sys/types.h> #include <fcntl.h> int fcntl(int filedes, int action, argument);
fcntl
in SAS/C Library Reference, Third Edition, Volume 1,& Release 6.00 for a
description of fcntl
and the operating characteristics of
sockets.
#include <sys/types.h> #include <sys/socket.h> int getclientid(int domain, struct clientid *clientid);
getclientid
gets the identifier of the calling
application. domain
is AF_INET
. clientid
is a
pointer to the clientid
structure, which is filled on return
from the call. getclientid
is used in the givesocket
and takesocket
calls, which enable cooperative processes to
pass socket descriptors to each other.
Note:
getclientid
is only supported with non-integrated sockets.
getclientid
succeeds, it returns a 0
. Otherwise,
it returns a -1
and sets errno
to
indicate the type of error.
getclientid
is not portable to UNIX operating systems.
On a UNIX operating system, sockets can be transferred from parent to
child processes when the child process has been created via the
fork
system call.
getclientid
returns the client ID from
TCP/IP.
#include <stddef.h> #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> /* These three application routines implement communication */ /* between the parent task and this task. They use a means */ /* other than sockets to communicate. */ fromparent(void *, size_t); toparent(void *, size_t); postparent(void); /* This routine receives a socket from its parent */ /* task and store the descriptor into the integer pointed */ /* to by "s". */ recvsock(int *s) { struct clientid id; /* Get the clientid from TCP/IP. */ if (getclientid (AF_INET, &id)==-1) { perror ("Can't get client ID"); return -1; } /* Pass clientid to parent. */ toparent(&id,sizeof(id)); /* Get socket descriptor number from parent. */ fromparent(s, sizeof(*s)); /* Take socket from parent. */ if (takesocket(&id, *s)==-1) { perror ("takesocket failed"); return -1; } /* Tell parent that takesocket is completed. */ postparent(); return 0; }
givesocket
,
takesocket
#include <sys/param.h> int getdtablesize (void);
getdtablesize
returns the maximum number of
HFS files and sockets
that may be opened.
In a system without OpenEdition,
getdtablesize
returns the maximum file descriptor number that can be
returned for a socket.
getdtablesize
returns the maximum number of open HFS files
and sockets if it is successful, and it returns a
- 1
if it is not successful.
getdtablesize
to determine the maximum number of
sockets that can be opened and allocates storage for file descriptor
sets large enough to accomodate this maximum. The file descriptor sets
can be later passed to select.
Note that when file descriptor sets are allocated in this fashion, the
FD_ZERO
macro in <sys/types.h>
should not be used as it assumes a fixed size for these sets.
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> main() { int maxsockets; fd_set *readset, *writeset, *exceptset); int ready; /* get maximum number of sockets */ maxsockets = getdtablesize(); readset = calloc(1, (maxsockets+7)/8); writeset = calloc(1, (maxsockets+7)/8); exceptset = calloc(1, (maxsockets+7)/8); /* allocate storage for fd sets (8 bits per byte) */ . . . ready = select(maxsockets, readset, writeset, exceptset, NULL); /* wait for socket activity */ . . . }
sysconf
#include <netdb.h> struct hostent *gethostbyaddr(const char *addr, int len, int type);
gethostbyaddr
returns a
hostent
structure containing the host's name and other
information. This structure is typically used to obtain the name
of the host from the h_name
field.
Refer to "<netdb.h>
" for details on
the hostent
structure. For TCP/IP, addr
should point to
struct in_addr
or an unsigned long integer in network
byte order,
len
is normally the sizeof(struct in_addr)
, and
type
should be AF_INET
.
Host information is found either through the resolver or
in your system's equivalent of the /etc/hosts
file. Refer to
"gethostbyname
and Resolver Configuration" for
a description of the logic that determines how the host address is
found.
gethostbyaddr
succeeds, it returns a host address.
A null pointer indicates the network address was not found in the
network file.
gethostbyaddr
returns points to a static structure
within the library. You must copy the information from this structure
before you make further gethostbyname
, gethostbyaddr
,
or gethostent
calls.
gethostbyaddr
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
gethostbyaddr
is a combination of the
host file and resolver versions of the BSD UNIX Socket
Library gethostbyaddr
function.
gethostbyname
,
gethostent
,
sethostent
#include <netdb.h> struct hostent *gethostbyname(const char *name);
gethostbyname
returns a pointer to
the
hostent
structure containing the host's IP address and other
information. Refer to <netdb.h> for
details on
the hostent
structure. This structure is typically used to find the previous
address of the host via the h_addr
field. Host information
is found either through the resolver or
in your system's equivalent of the /etc/hosts
file. Refer
to
gethostbyname and Resolver Configuration for
a description of the logic that determines how the host name is
found.
gethostbyname
succeeds, it returns a pointer to a host
name.
A null pointer indicates the network address was not found in the
network file.
gethostbyname
returns points to a static structure
within the library. You must copy the information from this structure
before you make further gethostbyname
, gethostbyaddr
,
or gethostent
calls.
gethostbyname
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
gethostbyname
is a combination of the
host file and resolver versions of the BSD UNIX Socket
Library gethostbyname
function.
gethostbyname
to return an IP address that corresponds to the
supplied hostname. gethostbyname
will determine if
a nameserver or local host tables are being used for
name resolution. The answer is returned in the
hostent structure, hp
and then printed.
The local host must be properly configured for name
resolution by either a nameserver or host tables.
#include <sys/types.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> main(int argc, char *argv[]) { struct hostent *hp; struct in_addr ip_addr; /* Verify a "hostname" parameter was supplied */ if (argc <1 || *argv[1] == '\0') exit(EXIT_FAILURE); /* call gethostbyname() with a host name. gethostbyname() returns a */ /* pointer to a hostent struct or NULL. */ hp = gethostbyname(argv[1]); if (!hp) { printf("%s was not resolved\n",argv[1]); exit(EXIT_FAILURE); } /* move h_addr to ip_addr. This enables conversion to a form */ /* suitable for printing with the inet_ntoa() function. */ ip_addr = *(struct in_addr *)(hp->h_addr); printf("Hostname: %s, was resolved to: %s\n", argv[1],inet_ntoa(ip_addr)); exit(EXIT_SUCCESS); }
gethostbyaddr
,
herror
,
sethostent
#include <netdb.h> struct hostent *gethostent(void);
gethostent
returns the next sequential entry in the
host file.
gethostent
succeeds, it returns a pointer to the
hostent
structure. Refer to <netdb.h>
for details on the hostent
structure.
A null pointer indicates an error occured or there were no more
nework entries. If the resolver
and the name server are in use,
gethostent
returns NULL
.
gethostent
returns points to a static structure
within the library. You must copy the information from this structure
before you make further gethostbyname
, gethostbyaddr
,
or gethostent
calls.
gethostent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
gethostent
is a combination of the
host file and resolver versions of the BSD UNIX Socket
Library gethostent
function.
gethostent
, endhostent
, and sethostent
.
The local host must be configured to use hosts tables
for name resolution, prefix.ETC.HOSTS; where prefix
is described in Network Administration .
#include <sys/types.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #define TRUE 1 static void prthost(struct hostent *h); main(int argc, char *argv[]) { struct hostent *h; /* sethostent() opens the prefix.ETC.HOSTS file, or when using a */ /* nameserver, opens a TCP connection to the nameserver. */ sethostent(TRUE); /* gethostent() reads the next sequential entry in the */ /* prefix.ETC.HOSTS file. It returns a pointer to a "hostent" */ /* structure. */ while (h=gethostent()) prthost(h); /* endhostent() closes the prefix.ETC.HOSTS file, or the */ /* connection to the nameserver. */ endhostent(); exit(EXIT_SUCCESS); } /* prthost() prints the information returned by gethostent() */ /* from the hostent structure. */ static void prthost(struct hostent *h) { char **p; /* Print primary name and aliases. */ printf("\nname: %s\n",h->h_name); for (p=h->h_aliases; *p; p++) printf("alternate name: %s\n",*p); /* Handle unexpected situations gracefully. */ if (h->h_addrtype != AF_INET) { printf("Not an internet address.\n"); return; } if (h->h_length != sizeof(struct in_addr)) { printf("Invalid length: %d.\n",h->h_length); return; } /* Print the primary address and any alternates. */ for (p=h->h_addr_list; *p; p++) { printf("%s address: %s\n", p==h->h_addr_list ? "primary " : "alternate ", inet_ntoa((*(struct in_addr *)*p)) ); } }
endhostent
,
gethostbyname
,
sethostent
#include <netdb.h> unsigned long gethostid(void);
gethostid
gets the 32-bit Internet address for the local
host.
gethostid
returns the Internet address or -1
(0xFFFFFFFF
),
which is the value of the macro identifier INADDR_NONE
in the
<netinet/in.h>
header file.
gethostid
calls are not necessarily portable to all systems. In particular,
the return value may not be the IP address. However, gethostid
is portable to many other environments, including most
UNIX systems, that implement BSD
sockets. These other socket library implementations do not require
the inclusion of the <netdb.h>
header file. The SAS/C
<netdb.h>
header file contains #pragma map
statements to create unique eight-character identifiers for the
MVS and CMS linking utilities. To reduce incompatibilities caused
by failure to include
<netdb.h>
in existing source code,
a #pragma map
statement for this
function is also available in <sys/types.h>
.
gethostid
returns is assigned by
the local
host's TCP/IP software, which must be running in order for
gethostid
to succeed.
gethostid
to
return the 32-bit internet address for the local host.
The local host must have an operational TCPIP stack.
#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> main() { struct in_addr in; /* gethostid() returns the 32-bit internet address as an */ /* unsigned long. */ in.s_addr = gethostid(); if (in.s_addr == INADDR_NONE) { perror("gethostid failed"); return EXIT_FAILURE; } /* convert the unsigned long to a string in dotted decimal */ /* and print. */ printf("Local Host IP Address is: %s\n",inet_ntoa(in)); return EXIT_SUCCESS; }
gethostname
int gethostname(char *name, int namelen);
gethostname
returns the host name for the current
processor. namelen
is the size of the name
array. The returned host name is null-terminated unless there is
not enough space in namelen
.
gethostname
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
gethostname
is portable to other environments, including
most
UNIX systems, that implement BSD
sockets. These other socket library implementations do not require
the inclusion of the <netdb.h>
header file. The SAS/C
<netdb.h>
header file contains #pragma map
statements to create unique eight-character identifiers for the
MVS and CMS linking utilities.
gethostname
returns is assigned by
the local
host's TCP/IP software, which must be running in order for
gethostid
to succeed.
gethostname
is portable to other environments, including most
UNIX systems, that implement BSD
sockets. To reduce incompatibilities caused by failure to include
<netdb.h>
in existing source code, a #pragma map
statement for
this function is also available in <sys/types.h>
.
gethostname
to
return the hostname as defined to the local host.
The local host must have an operational TCPIP stack.
#include <stdlib.h> #include <netdb.h> #include <stdio.h> main() { char buf[128]; /* gethostname returns the hostname in the buf array. If */ /* gethostname() succeeds it returns a 0, otherwise a -1 and */ /* errno is set accordingly. */ if (gethostname(buf,sizeof(buf))) { perror("Can't retrive host name"); return EXIT_FAILURE; } printf("%s\n",buf); return EXIT_SUCCESS; }
gethostbyname
,
gethostid
#include <sys/types.h> #include <arpa/nameser.h> GETLONG(l_int, msgp) u_long _getlong(const u_char *msgp);
GETLONG
macro and _getlong
function
extract an unsigned long
integer l_int
from a character buffer addressed by msgp
.
The bytes of the extracted integer
are assumed to have been
stored in the buffer as four consecutive bytes, starting with the
high-order byte. The _getlong
function returns the value.
The GETLONG
macro requires that both arguments be
lvalues.
mgsp
is advanced by four bytes.
The extracted unsigned long value is assigned to l_int
.
This routine is useful in resolver programming. For information on buffer formats for Internet name servers, refer to Chapter 20, "The Domain Name System," in Internetworking with TCP/IP.
_getlong
returns the value of the unsigned long integer.
GETLONG
is syntactically a statement rather than an expression and, therefore,
has no return value.
GETLONG
evaluates its arguments more than once.
GETLONG
macro is defined in the
<arpa/nameser.h>
header file.
GETSHORT
,
PUTLONG
,
PUTSHORT
#include <netdb.h> struct netent *getnetbyaddr(long net, int type);
net
,
getnetbyaddr
returns a pointer to
the netent
structure as defined in <netdb.h>
.
This structure typically is used
to obtain the network name from the n_name
field. The
network address should be supplied in host byte order. For TCP/IP,
type
should be AF_INET
. Refer to <netdb.h>
for details on
the netent
structure.
The source of the data in the netent
structure is the network file, that is, a file with the same format as
the /etc/networks
file on a UNIX operating system.
Refer to Search Logic for information on the logic used to determine the location of the network file.
getnetbyaddr
succeeds, it returns a pointer to the
netent
structure.
A null pointer indicates the network address was not found in the
network file.
getnetbyaddr
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getnetbyname
, getnetbyaddr
,
or getnetent
calls.
getnetbyaddr
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getnetbyaddr
is ported directly from the BSD UNIX Socket
Library.
getnetent
,
getnetbyname
,
setnetent
,
endnetent
#include <netdb.h> struct netent *getnetbyname(const char *name);
name
argument,
getnetbyname
returns a pointer to the
netent
structure, as defined in <netdb.h>
.
Refer to <netdb.h>
for details on
the netent
structure. This structure is typically used to obtain the network
address from the n_net
field. The source of the data in this
structure is the network file, that is, a file with the same format as
the /etc/networks
file on a UNIX operating system.
Refer to Search Logic for information on the logic used to determine the location of the network file.
getnetbyname
succeeds, it returns a pointer to the
netent
structure.
A null pointer indicates the network address was not found
in the network file.
getnetbyname
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getnetbyname
, getnetbyaddr
,
or getnetent
calls.
getnetbyname
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getnetbyname
is ported directly from the BSD UNIX Socket
Library.
getnetbyaddr
,
getnetent
,
setnetent
,
endnetent
#include <netdb.h> struct netent *getnetent(void);
getnetent
returns a pointer to the next
network entry in the netent
structure
as defined in <netdb.h>
.
The source of the data in this structure is the network file, that is,
a file with the same format as the /etc/networks
file on a
UNIX operating system. Refer to <netdb.h>
for details
on the netent
structure.
Refer to Search Logic for information on the logic used to determine the location of the network file.
getnetent
succeeds, it returns a pointer to the
netent
structure.
A null pointer indicates an error occurred or there were no more
network entries.
getnetent
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getnetbyname
, getnetbyaddr
,
or getnetent
calls.
getnetent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getnetent
is ported directly from the BSD UNIX Socket
Library.
getnetbyaddr
,
getnetbyname
,
setnetent
,
endnetent
#include <sys/types.h> #include <sys/socket.h> int getpeername(int s, void *addr, int *addrlen);
getpeername
stores the address of the peer
that is
connected to socket s
. The addr
and addrlen
functions
describe the buffer into which
getpeername
places the address of the new peer.
addr
points to a sockaddr
structure
or one of its derivatives, such
as sockaddr_in
, and addrlen
points to an integer containing the size of the buffer in bytes. If
the buffer size is not large enough to contain the address of the
peer, the value of the address is not completely copied. No error
is indicated
in this situation. On return, the integer pointed to by
addrlen
is set to
the length that was
actually copied. For connected sockets, the address that is returned is
the same as that returned by the recvfrom
function.
getpeername
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
getpeername
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getpeername
returns the
port and address of the peer program.
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> f() { int s; struct sockaddr_in peer; int peer_len; . . . /* We must put the length in a variable. */ peer_len = sizeof(peer); /* Ask getpeername to fill in peer's socket address. */ if (getpeername(s, &peer, &peer_len) == -1) { perror("getpeername() failed"); return -1; } /* Print it. The IP address is often zero because */ /* sockets are seldom bound to a specific local */ /* interface. */ printf("Peer's IP address is: %s\n", inet_ntoa(peer.sin_addr)); printf("Peer's port is: %d\n", (int) ntohs(peer.sin_port)); . . . }
accept
,
bind
,
connect
,
getsockname
,
recvfrom
#include <netdb.h> struct protoent *getprotobyname(char *name);
getprotobyname
returns a pointer to
the protoent
structure defined in <netdb.h>
.
This structure is typically used to
obtain the number for the protocol from the p_proto
field.
Refer to <netdb.h>
for details on
the protoent
structure. The source of the data in this
structure is the protocols file, that is, a file with the same
format
as the /etc/protocols
file on a UNIX operating system.
Refer to Search Logic
for
information on the logic used to determine the location of the
protocols file.
getprotobyname
succeeds, it returns a pointer to the
protoent
structure.
A null pointer indicates the network address was not found in the
network file.
getprotobyname
returns points to a static
structure
within the library. You must copy the information from this structure
before you make further getprotobyname
, getprotobynumber
,
or getprotoent
calls.
getprotobyname
is portable to other environments,
including most UNIX systems, that implement BSD
sockets.
getprotobyname
is ported directly from the BSD UNIX Socket
Library.
endprotoent
,
setprotoent
,
getprotobynumber
,
getprotoent
#include <netdb.h> struct protoent *getprotobynumber(int proto);
proto
,
getprotobynumber
returns a
pointer to the protoent
structure defined in <netdb.h>
for the
specified network protocol
proto
. Refer to <netdb.h>
for details on
the protoent
structure. This structure is typically used to obtain the name of the
protocol from the p_name
field. The source of the data in
this
structure is the protocols file, that is, a file with the same
format
as the /etc/protocols
file on a UNIX operating system.
Refer to Search Logic for information on the logic used to determine the location of the protocols file.
getprotobynumber
succeeds, it returns a pointer to the
protoent
structure.
A null pointer indicates the network address was not found in the
network file.
getprotobynumber
returns points to a static
structure
within the library. You must copy the information from this structure
before you make further getprotobyname
, getprotobynumber
,
or getprotoent
calls.
getprotobynumber
is portable to other environments, including
most UNIX systems, that implement BSD
sockets.
getprotobynumber
is ported directly from the BSD UNIX Socket
Library.
endprotoent
,
setprotoent
,
getprotobyname
,
getprotoent
#include <netdb.h> struct protoent *getprotoent(void);
getprotoent
returns a pointer to the
next network entry in the
protoent
structure defined in <netdb.h>
.
Refer to <netdb.h>
for details on
the protoent
structure. The source of the data in this
structure is the protocols file, that is, a file with the same
format
as the /etc/protocols
file on a UNIX operating system.
Refer to Search Logic for information on the logic used to determine the location of the protocols file.
getprotoent
succeeds, it returns a pointer to the
protoent
structure.
A null pointer indicates an error occurred or there were no more network
entries.
getprotoent
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getprotobyname
, getprotobynumber
,
or getprotoent
calls.
getprotoent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getprotoent
is ported directly from the BSD UNIX Socket
Library.
endprotoent
,
setprotoent
,
getprotobyname
,
getprotobynumber
rpcent
Structure for an RPC Program Name#include <netdb.h> struct rpcent *getrpcbyname(const char *name);
name
argument, getrpcbyname
returns a pointer
to the rpcent
structure defined in <netdb.h>
. This structure
is typically used to obtain the number for the RPC program from the
r_number
field. Refer to rpcent
for details on the rpcent
structure.
The source of the data in the rpcent
structure is the protocols
file, that is, a file with the same format as the /etc/rpc
file on a
UNIX operating system. Refer to /etc/rpc
for information on the logic used to determine the location of
the protocols file.
getrpcbyname
succeeds, it returns a pointer to the rpcent
structure. A null pointer indicates an error or an end-of-file.
getrpcbyname
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getrpcbyname
, getrpcbynumber
, or
getrpcent
calls.
getrpcbyname
is portable to other systems that support Sun RPC
4.0.
endrpcent
, getrpcbynumber
, getrpcent
, setrpcent
rpcent
Structure for an RPC Program Number#include <netdb.h> struct rpcent *getrpcbynumber(int prognum);
prognum
,
getrpcbynumber
returns a
pointer to the rpcent
structure, which is
defined in <netdb.h>
. This
structure is typically used to obtain the name for the RPC program from
the r_name
field. Refer to rpcent
for details on the rpcent
structure.
The source of the data in the rpcent
structure is the protocols
file, that is, a file with the same format as the /etc/rpc
file on a
UNIX operating system. Refer to /etc/rpc
for information on the logic used to determine the location of
the protocols file.
getrpcbynumber
succeeds, it returns a pointer to the
rpcent
structure. A null pointer indicates
the network address was not found in the network file.
getrpcbynumber
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getrpcbyname
, getrpcbynumber
, or
getrpcent
calls.
getrpcbynumber
is portable to other systems that support Sun RPC
4.0.
endrpcent
, getrpcbyname
, getrpcent
, setrpcent
rpcent
Structure#include <netdb.h> struct rpcent *getrpcent(void);
getrpcent
returns a pointer to the rpcent
structure,
which is defined
in <netdb.h>
. The source of
the data in this structure is the SUN RPC
program numbers file, that is, a file with
the same format as the /etc/rpc
file on a UNIX operating system.
Refer to /etc/rpc for information on the logic used to determine the location of the protocols file.
getrpcent
succeeds, it returns a pointer to the rpcent
structure. A null pointer indicates an error occurred or there were no
more network entries.
getrpcent
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getrpcbyname
, getrpcbynumber
, or
getrpcent
calls.
getrpcent
is portable to other systems that support Sun RPC 4.0.
endrpcent
, getrpcbyname
, getrpcbynumber
, setrpcent
#include <netdb.h> struct servent *getservbyname(const char *name, const char *proto);
name
,
and a protocol string for
accessing that service, pointed to by proto
,
getservbyname
returns a pointer to the
servent
structure, which is defined in <netdb.h>
.
This structure is typically used to obtain the port for the service
from the serv_port
field. The source of the data in this
structure is the services file, that is, a file with the
same format
as the /etc/services
file on a UNIX operating
system. Refer to
<netdb.h>
for details on
the servent
structure.
Refer to Search Logic for information on the logic used to determine the location of the services file.
getservbyname
succeeds, it returns a pointer to the
servent
structure.
A null pointer indicates an error or an end-of-file.
getservbyname
returns points to a static
structure
within the library. You must copy the information from this structure
before you make further getservbyname
, getservbyport
,
or getservent
calls.
getservbyname
is portable to other environments, including
most UNIX systems, that implement BSD
sockets.
getservbyname
is ported directly from the BSD UNIX Socket
Library.
getservbyname
to obtain the structure, servent. In most cases the
returned structure is used to obtain the port for the
service. getservbyname
reads the prefix.ETC.SERVICES
file.
The prefix
.ETC.SERVICES file must be properly
configures on the local host; where prefix is
described in Network Administration .
The input parameters are case sensitive.
#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> main(int argc, char *argv[]) { struct servent *serv; if (argc < 3) { puts("Incorrect parameters. Use:"); puts(" gsbnm service-name protocol-name"); return EXIT_FAILURE; } /* getservbyname() - opens the etc.services file and returns the */ /* values for the requested service and protocol. */ serv = getservbyname(argv[1], argv[2]); if (serv == NULL) { printf("Service \"%s\" not found for protocol \"%s\"\n", argv[1], argv[2]); return EXIT_FAILURE; } /* Print it. */ printf("Name: %-15s Port: %5d Protocol: %-6s\n", serv->s_name,ntohs(serv->s_port),serv->s_proto); return EXIT_SUCCESS; }
endservent
,
setservent
,
getservent
,
getservbyport
#include <netdb.h> struct servent *getservbyport(int port, const char *proto);
port
argument, and the protocol string for accessing
it, pointed to by proto
, getservbyport
returns a
pointer to the servent
structure, which is defined in <netdb.h>
.
This structure is typically used to obtain the name of the service
from the s_name
field. The source of the data in this
structure is the services file, that is, a file with the
same format as the /etc/services
file on a UNIX operating
system. Refer to <netdb.h>
for details on
the servent
structure.
Refer to Search Logic for information on the logic used to determine the location of the services file.
getservbyport
succeeds, it returns a pointer to the
matching port number in the
servent
structure.
A null pointer indicates an error occurred or there
were no more network entries.
getservbyport
returns points to a static
structure
within the library. You must copy the information from this structure
before you make further getservbname
, getservbyport
,
or getservent
calls.
getservbyport
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getservbyport
is ported directly from the BSD UNIX Socket
Library.
endservent
,
setservent
,
getservent
,
getservbyname
#include <netdb.h> struct servent *getservent(void);
getservent
returns a pointer to the next sequential entry in
the services file, that is, a file with the
same format as the /etc/services
file on a UNIX operating
system. Refer to <netdb.h> for details on
the servent
structure.
Refer to Search Logic for information on the logic used to determine the location of the services file.
getservent
succeeds, it returns a pointer to the
servent
structure.
A null pointer indicates an error or an end-of-file.
getservent
returns points to a static
structure
within the library. You must copy the information from this structure
before you make further getservbyname
, getservbyport
,
or getservent
calls.
getservent
is portable to other environments, including most
UNIX systems, that implement BSD sockets.
getservent
is ported directly from the BSD UNIX Socket
Library.
endservent
, getservent
, and setservent
.
GETSENT attempts to open a prefix.ETC.SERVICES file to
obtain local configuration data; where prefix
is described in Network Administration .
#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #define TRUE 1 main() { struct servent *serv; /* setservent() opens the ETC.SERVICES file. */ setservent(TRUE); /* getservent() sequentially reads the elements in the */ /* ETC.SERVICES file. */ while (serv = getservent()) { /* Print an entry. */ printf("Name: %-15s Port: %5d Protocol: %-6s\n", serv->s_name,ntohs(serv->s_port),serv->s_proto); } /* endservent() closes the ETC.SERVICES file. */ endservent(); return EXIT_SUCCESS; }
endservent
,
setservent
,
getservbyname
,
getservbyport
#include <sys/types.h> #include <arpa/nameser.h> GETSHORT(s_int, msgp) u_short _getshort(const u_char *msgp);
GETSHORT
macro and _getshort
function
extract an unsigned short
integer s_int
from a character buffer addressed by msgp
.
The bytes of the extracted integer
are assumed to have been
stored in the buffer as two consecutive bytes, starting with the
high-order byte. The _getshort
function returns the
value. The GETSHORT
macro requires that both arguments are
lvalues. mgsp
is advanced by two bytes. The extracted
unsigned short value is assigned to s_int
.
This routine is useful in resolver programming. For information on buffer formats for Internet name servers, refer to Chapter 20, "The Domain Name System," in Internetworking with TCP/IP.
_getshort
returns the value of the
unsigned short integer. GETSHORT
is syntactically a statement rather than an expression, and therefore
has no return value.
GETSHORT
evaluates its arguments more than once.
GETSHORT
macro is defined in the
<arpa/nameser.h>
header file.
GETLONG
,
PUTLONG
,
PUTSHORT
#include <sys/types.h> #include <sys/socket.h> int getsockname(int s, void *addr, int *addrlen);
getsockname
stores the address that is bound
to a
specified socket s
in the buffer pointed to by addr
.
The addr
and addrlen
functions describe the buffer into which
getsockname
places the address of the socket.
addr
, as specified in the previous bind
call,
should point to a sockaddr
structure
or one of its derivatives, such as sockaddr_in
.
addrlen
points to an integer containing the size of the buffer in bytes. If
the buffer size is not large enough to contain the address of the
socket, the value of the address is not completely copied. No
error is indicated in this situation. On return, the integer pointed
to by addrlen
is set to
the length that was
actually copied. If the socket has not been bound to an address, only
the sa_family
field is meaningful; all other fields are set
to 0
.
getsockname
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
getsockname
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getsockname
returns the name of
bound socket s
.
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> f() { int s; struct sockaddr_in sa; int sa_len; . . . /* We must put the length in a variable. */ sa_len = sizeof(sa); /* Ask getsockname to fill in this socket's local */ /* address. */ if (getsockname(s, &sa, &sa_len) == -1) { perror("getsockname() failed"); return -1; } /* Print it. The IP address is often zero beacuase */ /* sockets are seldom bound to a specific local */ /* interface. */ printf("Local IP address is: %s\n", inet_ntoa(sa.sin_add r)); printf("Local port is: %d\n", (int) ntohs(sa.sin_port)); . . . }
bind
,
getpeername
#include <sys/types.h> #include <sys/socket.h> int getsockopt(int s, int level, int optname, void *optval, int *optlen);
getsockopt
returns the value of an option associated
with socket
s
. The level
argument is the level of the option.
The optname
argument is the name of the option. The optval
argument is a
pointer to the buffer that receives the value of the
requested option.
As an input parameter, the integer pointed to by optlen
should be set to the size of the
optval
buffer. On output, the integer pointed to by
optlen
is set to the size of
the returned value. For cases in which optval
points
to an integer, a stored value of 0
indicates that the option
is off. A nonzero returned value indicates that the option is on.
Most options are at the socket level. Pass SOL_SOCKET
as the
level
parameter for these options:
SO_ERROR
errno
value (the
SO_ERROR
field on a UNIX operating system)
for each socket. The SO_ERROR
option obtains and then clears this
field, which is useful when checking for errors that occur between
socket calls. In this case, optval
should point to an
integer.
SO_LINGER
linger
option.
The linger
option controls the behavior
of the call to close
when
some data have not yet been sent. optval
should point to
a struct linger
. If the value of the l_onoff
field
is 0
, close
returns immediately. In this case, TCP/IP continues to
attempt to deliver the data, but the program is not informed if
delivery fails. If the value of the l_onoff
field is
nonzero, the behavior of the close
call depends on the value of the
l_linger
field. If this value is 0
, unsent data are
discarded at the
time of the close
. If the value of l_linger
is
not 0
, the close
call blocks the caller until there is a
timeout or until all data are sent. The l_linger
field
indicates the length of the desired timeout period. Some TCP/IP
implementations may ignore the value of the l_linger
field.
s
must be a stream socket.
SO_OOBINLINE
MSG_OOB
flag in
recv
calls. optval
should point to an integer.
s
must be a stream socket. Refer to "Out-of-Band Data"
in Chapter 6,
"Berkeley Sockets," in UNIX Network Programming for information
on out-of-band data.
SO_REUSEADDR
optval
should
point to an integer.
s
must be a stream socket.
SO_TYPE
SOCKET_STREAM
, SOCK_RAW
, or
SOCK_DGRAM
. The
optval
pointer should
point to an integer.
IPPROTO_TCP
is available for one option.
The
TCP_NODELAY
option indicates that TCP's normal socket buffering
should not be used on the socket. The TCP_NODELAY
option is
not operative; it
is supported for source code compatibility. The
<netinet/in.h>
and <netinet/tcp.h>
headers files are
required for this
option.
getsockopt
succeeds, it returns a 0
. Otherwise,
it returns a -1
and sets errno
to
indicate the type of error.
getsockopt
is portable to other environments, including most
UNIX systems, that implement BSD
sockets. The supported options may vary depending on the system,
and the options described previously may be supported differently.
Additional
options may be supported by a specific TCP/IP software
product. Refer to your
software documentation for details.
getsockopt
gets the type of socket.
#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> main() { int optlen, gs, socktype, s; /* Create a datagram socket. */ s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) { perror("Socket not created"); return EXIT_FAILURE; } /* Ask for the socket type. */ optlen = sizeof(socktype); gs = getsockopt (s, SOL_SOCKET, SO_TYPE, &socktype, &optlen); if (gs == -1) { perror("getsockopt failed"); return EXIT_FAILURE; } /* Print socket type. */ switch (socktype) { case SOCK_STREAM: puts("Stream socket.\n"); break; case SOCK_DGRAM: puts("Datagram socket.\n"); break; case SOCK_RAW: puts("Raw socket.\n"); break; default: puts("Unknown socket type.\n"); break; } return EXIT_SUCCESS; }
bind
,
close
,
fcntl
,
ioctl
,
recv
,
setsockopt
,
socket
#include <sys/types.h> #include <sys/socket.h> int givesocket(int s, const struct clientid * clientid);
givesocket
specifies that socket s
is
available to another process.
s
must be a connected stream socket. After a successful
givesocket
call, the donor process, which is often a
concurrent server, passes its client ID clientid
and the
socket descriptor for s
to the receiving process. The donor
process must have already obtained the client ID of the receiving
process.
To pass a socket, the donor program calls givesocket
with
the clientid
structure filled in as follows:
Field Description
domain AF_INET name Receiving program's address space name, left justified and padded with blanks subtaskname blanks reserved binary zeros
takesocket
call. The mechanism for exchanging client IDs and
socket descriptor values is the responsibility of the two processes
and is not
accomplished by either the givesocket
or the takesocket
call.
If givesocket
is successful, s
is not available
for any other calls until a close
is issued for s
.
Do not issue a close
call until the other application has
successfully completed a takesocket
call for s
;
otherwise the connection is reset.
The select
or selectecb
functions can be used
to wait on an exception condition for a given socket. An
exception condition is raised on a socket when the
receiver has taken the socket with the socket
function.
When the exception is raised, the donor program can close the socket.
Note:
givesocket
is only supported with non-integrated sockets.
givesocket
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
givesocket
is not portable to UNIX operating systems.
On UNIX operating systems, sockets are typically transferred from
parent to child processes as a side effect of the fork
system call.
getclientid
,
select
,
selectecb
,
takesocket
#include <netdb.h> void herror(const char *string);
herror
writes an error message to stderr
describing a failure in
gethostbyname
or gethostbyaddr
. If string
is not NULL
,
it is written first,
followed by a colon, a space,
and the error message corresponding to the h_errno
value.
h_errno
values and herrno
text are as follows:
h_error value herror text
HOST_NOT_FOUND Host not found. TRY_AGAIN Temporary failure, try later. NO_RECOVERY Nameserver failure NO_DATA No data of this type associated with this name NO_ADDRESS No address of this type associated with this name.
herror
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
gethostbyaddr
,
gethostbyname
#include <sys/types.h> #include <netinet/in.h> int htoncs(int hostchar);
htoncs
converts a single EBCDIC character hostchar
to an ASCII character. High-order bits will be ignored in the input
parameter. The
name of this function, an abbreviation of "host to
network character set," is analogous to the htonl
and
htons
functions. ASCII is the predominant character set for text on
TCP/IP networks,
while EBCDIC is the predominant character set for text on MVS
and CMS systems.
The htoncs
function is provided to facilitate the writing of
TCP/IP programs on MVS and CMS systems. You may find that other
EBCDIC-to-ASCII translation routines are better suited to your
requirements.
htoncs
returns the ASCII character corresponding
to the input argument interpreted as an EBCDIC character.
htoncs
is not portable; character set translation is seldom
required in other environments.
htonl
,
htons
,
ntohcs
,
ntohl
,
ntohs
#include <sys/types.h> #include <netinet/in.h> unsigned long htonl(unsigned long hostlong);
htonl
macro converts an unsigned long integer
hostlong
from host byte order to network
byte order. On an IBM 370, this is a null macro since IBM 370 byte
ordering is big endian, as is network byte ordering.
htonl
returns the converted value.
htonl
function. Be sure to include the proper
header files so that the htonl
macro is always used.
htonl
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
htonl
macro is defined in the <netinet/in.h>
header file.
htoncs
,
htons
,
ntohcs
,
ntohs
,
ntohl
#include <sys/types.h> #include <netinet/in.h> unsigned short htons(unsigned short hostshort);
htons
macro converts an unsigned
short integer hostshort
from host byte order to network
byte order. On an IBM 370, this is a null macro since IBM 370 byte
ordering is big endian, as is network byte ordering.
htons
returns the converted value.
htons
function. Be sure to include the
proper
header files so that the htons
macro is always used.
htons
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
htons
macro is defined in the <netinet/in.h>
header
file.
htoncs
,
htonl
,
ntohcs
,
ntohs
,
ntohl
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> unsigned long inet_addr(const char *cp);
inet_addr
interprets a null-terminated
character string, pointed to by cp
, that represents numbers
in the Internet standard dotted decimal notation and returns
a corresponding
Internet address. The dotted decimal string can
contain up to four components. All but the last components are placed in
succeeding bytes, beginning with the high-order byte. The last
component fills all remaining bytes. This dotted decimal notation
takes one of the following forms:
a.b.c.d
a.b.c
a.b
a.
The numbers supplied in dotted decimal notation
can be decimal,
octal,
or hexadecimal, as specified in the C language. In other words,
a leading 0x
or
0X
implies hexadecimal notation; a leading 0
implies octal notation.
Otherwise, the number is interpreted as decimal.
The Internet address is returned in network byte order.
inet_addr
is successful, it returns the address in
network byte order. Otherwise, it returns a -1UL
(0xFFFFFFFF
),
and sets errno
to
indicate the type of error. INADDR_NONE is the
symbolic name for
the -1UL
value returned by inet_addr
when the input is valid.
inet_addr
is portable to other environments, including most
UNIX systems, that implement BSD
sockets. On some systems, this routine may return the type
struct in_addr
.
inet_addr
is a direct port from
the BSD UNIX Socket Library.
inet_lnaof
,
inet_makeaddr
,
inet_netof
,
inet_network
,
inet_ntoa
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> unsigned long inet_lnaof(struct in_addr in);
inet_lnaof
separates the elements in an Internet host
address, specified by in
, and returns the local network address.
The host address is in network byte order because it is contained in a
struct in_addr
.
inet_lnaof
returns the network address in
host byte order.
inet_lnaof
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
inet_lnaof
is a direct port from
the BSD UNIX Socket Library.
inet_addr
,
inet_makeaddr
,
inet_netof
,
inet_network
,
inet_ntoa
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> struct in_addr inet_makeaddr(int net, int lna);
inet_makeaddr
constructs an Internet address from an
Internet network number net
and a local network address
lna
.
Both the Internet network number and the local network address are
specified in host byte order.
inet_makeaddr
returns the Internet address in
network byte order.
inet_makeaddr
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
inet_makeaddr
is a direct port from
the BSD UNIX Socket Library.
inet_addr
,
inet_lnaof
,
inet_netof
,
inet_network
,
inet_ntoa
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> unsigned long inet_netof(struct in_addr in);
inet_netof
separates the elements in an Internet host
address in
and returns the network number.
The host address is specified in network byte order because it is
contained in a struct in_addr
.
inet_netof
returns the network number in
host byte order.
inet_netof
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
inet_netof
is a direct port from
the BSD UNIX Socket Library.
inet_addr
,
inet_lnaof
,
inet_makeaddr
,
inet_network
,
inet_ntoa
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> unsigned long inet_network(const char *cp);
inet_network
interprets a null-terminated
character string, pointed to by cp
, that represents numbers
in the Internet standard dotted decimal notation and returns that
string as an Internet network number of up to four components. Each
component is assigned to a byte of the result. If there are fewer
than four components, high-order bytes have a value of 0
.
The numbers supplied in dotted decimal notation
can be decimal,
octal,
or hexadecimal, as specified in the C language. In other words,
a leading 0x
or
0X
implies hexadecimal notation; a leading 0
implies octal notation.
Otherwise, the number is interpreted as decimal.
inet_network
is successful, it returns the network number.
Otherwise, it returns a -1
, and sets errno
to
indicate the type of error. INADDR_NONE
is the
symbolic name for
the -1
value returned by inet_network
when the input is valid.
inet_network
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
inet_network
is a direct port from
the BSD UNIX Socket Library.
inet_lnaof
,
inet_makeaddr
,
inet_netof
,
inet_addr
,
inet_ntoa
#include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> char *inet_ntoa(struct in_addr in);
inet_ntoa
takes an Internet address, in
, and returns
a pointer to a null-terminated string representing the address in
dotted decimal notation. The dotted decimal string has four
components.
The host address is specified in network byte order because it is
contained in a struct in_addr
.
inet_ntoa
is successful, it
returns a pointer to the Internet
address in dotted decimal notation.
inet_ntoa
call.
inet_ntoa
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
inet_ntoa
is a direct port from
the BSD UNIX Socket Library.
inet_addr
,
inet_lnaof
,
inet_makeaddr
,
inet_network
,
inet_netof
#include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <if.h> int ioctl(int s, unsigned long cmd, void *data);
ioctl
controls or queries
the operating characteristics of socket descriptor
s
. data
points to the data that are
associated with command cmd
.
The following commands are valid:
FIONBIO
s
, and data
points to
an integer. If *data
is 0
, ioctl
clears
non-blocking I/O. If *data
is not 0
, s
is
set for non-blocking I/O. Calls that cannot complete
immediately return a -1
with errno
set to
EWOULDBLOCK
.
FIONREAD
s
; data
points to an integer, which is set to the number of readable
characters for s
.
SIOCATMARK
s
is pointing to out-of-band data.
data
points to an integer, which is set to 1
if s
points to out-of-band data. Otherwise, *data
is set to 0
.
Use this option for TCP sockets where out-of-band data are
delivered
inline. Refer to "Out-of-Band Data" in Chapter 6, "Berkeley
Sockets," in UNIX Network Programming.
SIOCGIFADDR
data
points
to an ifreq
structure that is
defined in <if.h>
. The address
is returned in the if_addr
field.
SIOCGIFBRDADDR
data
points
to an ifreq
structure that is
defined in <if.h>
. The address
is returned in the if_broadaddr
field.
SIOCGIFCONF
data
points
to an ifconf
structure that is defined in <if.h
>.
On input, the structure specifies a buffer into which the list is
placed. The ifc_buf
field should point to the buffer. The
ifc_len
field should contain its length in bytes.
SIOCGIFDSTADDR
data
points
to an ifreq
structure that is defined
in <if.h>
. For
point-to-point connections, this option stores the address of
the
remote interface or destination.
The address
is stored in the if_dstadaddr
field.
SIOCGIFFLAGS
data
points
to an ifreq
structure that is defined in <if.h>
.
The flags provide information about the interface and its current
state, such as whether the interface is point-to-point and whether it
is currently up. The flags are stored in the ifr_flags
field of the ifreq
structure. The names of the flags
begin with IFF; they are listed in the <if.h>
header file.
SIOCGIFNETMASK
data
points
to an ifreq
structure that is defined
in <if.h>
. The address
is returned in the if_addr
field.
Note:
If integrated sockets are in use, the ioctl
function
simply calls the w_ioctl
OpenEdition system call.
ioctl
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
ioctl
is portable to other environments, including most
UNIX systems, that implement BSD
sockets. Unlike the BSD UNIX ioctl
call, the SAS/C
version of ioctl
controls only sockets.
fcntl
getsockopt
,
setsockopt
#include <sys/types.h> #include <sys/socket.h> int listen(int s, int backlog);
listen
indicates that the socket descriptor s
is ready to accept
incoming connection requests. backlog
is an integer
defining the maximum length of the queue of connection requests. The
SOMAXCONN constant in the <socket.h>
header file defines the
maximum value for the backlog
parameter. Currently,
SOMAXCONN
is 10
.
The
connections are accepted with accept
. Servers typically use
this call in preparation for service requests from clients.
listen
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
listen
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
accept
,
bind
,
connect
#include <sys/types.h> #include <netinet/in.h> int ntohcs(int netchar);
ntohcs
converts a network ASCII character netchar
to
a host EBCDIC character.
High-order bits will be ignored in input parameters.
The name of this function, an abbreviation
of "network
to host character set," is analogous to the names of the
ntohl
and ntohs
functions. ASCII is the standard character set for
text on TCP/IP
networks, while EBCDIC is the standard character set for
text on MVS
and CMS systems.
The ntohcs
function is provided to facilitate the writing of
TCP/IP programs on MVS and CMS systems. You may find that other
ASCII-to-EBCDIC translation routines are better suited
to your requirements.
ntohcs
returns the EBCDIC character corresponding
to netchar
interpreted as an ASCII
character.
ntohcs
is not portable; character set translation is seldom
required in other environments.
htoncs
,
htonl
,
htons
,
ntohl
,
ntohs
#include <sys/types.h> #include <netinet/in.h> unsigned long ntohl(unsigned long netlong);
ntohl
macro converts an unsigned
long integer netlong
from network byte order to
host byte order. On an IBM 370, this is a null macro, since IBM 370 byte
ordering is big endian, as is network byte ordering.
ntohl
returns the converted value.
ntohl
function. Be sure to include the
proper
header files so that the ntohl
macro is always used.
ntohl
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
ntohl
macro is defined in the <netinet/in.h>
header file.
htoncs
,
htonl
,
htons
,
ntohcs
,
ntohs
#include <sys/types.h> #include <netinet/in.h> unsigned short ntohs(unsigned short netshort);
ntohs
macro converts an unsigned
short integer netshort
from network byte order to host
byte order. On an IBM 370, this is a null macro, since IBM 370 byte
ordering is big endian, as is network byte ordering.
ntohs
returns the converted value.
ntohs
function. Be sure to include the
proper
header files so that the ntohs
macro is always used.
ntohs
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
ntohs
macro is defined in the <netinet/in.h>
header
file.
htoncs
,
htonl
,
htons
,
ntohcs
,
ntohl
#include <sys/types.h> #include <arpa/nameser.h> PUTLONG(ul, msgp) int putlong(u_long ul, u_char *msgp);
PUTLONG
macro and putlong
function put an
unsigned long
integer ul
into a character buffer addressed by msgp
.
The bytes of the integer are assumed to
have been
stored in the buffer as four consecutive bytes, starting with the
high-order byte. The putlong
function returns the value.
The PUTLONG
macro
requires that both
its arguments be lvalues. mgsp
is advanced by four bytes.
The value in ul
is destroyed by the macro.
These routines are useful in resolver programming. For information
on buffer formats for Internet name servers, refer to Chapter 20,
"The Domain Name System," in Internetworking with TCP/IP.
putlong
returns the value of the unsigned long integer.
PUTLONG
is syntactically a statement rather than an expression and, therefore,
has no return value.
PUTLONG
evaluates its arguments more than once.
The PUTLONG
macro destroys its first argument.
PUTLONG
macro is defined in the
<arpa/nameser.h>
header file.
GETLONG
,
GETSHORT
,
PUTSHORT
#include <sys/types.h> #include <arpa/nameser.h> PUTSHORT(u_sh, mgsp) int putshort(u_short u_sh, u_char *msgp);
PUTSHORT
macro and putshort
function put an
unsigned short integer u_sh
into a character buffer addressed by msgp
.
The PUTSHORT
macro requires that its second argument be
an lvalue.
mgsp
is advanced by two bytes.
This routine is useful in resolver programming. For information
on buffer formats for Internet name servers, refer to Chapter 20,
"The Domain Name System," in Internetworking with TCP/IP.
putshort
returns the value of the unsigned short
integer. PUTSHORT
is syntactically a statement rather than an expression, and, therefore,
has no return value.
PUTSHORT
evaluates its arguments more than once.
PUTSHORT
macro is defined in the
<arpa/nameser.h>
header file.
GETLONG
,
GETSHORT
,
PUTLONG
#include <sys/types.h> #include <sys/uio.h> #include <fcntl.h> int readv(int s, struct iovec *iov, int iovcnt);
readv
reads data from socket or file descriptor
s
into
the iovcnt
buffers specified by the iov
array.
As with the read
call, the socket must have been previously
associated with a remote address via the connect
system call.
If there are no data, readv
blocks the caller
unless the socket is in non-blocking mode. The iovec
structure is defined in <sys/uio.h>
.
Each iovec
entry
specifies
the base address and length of an area in memory in which the data
should be placed. readv
completely fills one area before
proceeding to the next area.
Note:
Although readv
is primarily used
with sockets, it can also be used to read any file that can be
accessed by the read
function.
readv
succeeds, it returns the number of bytes read into
the buffer. If readv
returns a 0
, the end-of-file has
been reached. If readv
fails, it
returns a -1
. It is common for readv
to return a value less
than the
total number of bytes in the buffers. This is not an error.
readv
is an atomic operation. With UDP, no more than one datagram can be
read per call. If you are using datagram sockets, make sure that
there is enough buffer space in the I/O vector to contain an incoming
datagram.
readv
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
connect
,
recv
,
recvfrom
,
recvmsg
,
write
,
writev
#include <sys/types.h> #include <sys/socket.h> int recv(int s, void *buf, int len, int flags);
recv
receives messages on socket s
and
stores them in the buffer buf
of length len
. The socket
must be connected or associated with a foreign peer via the
connect
function. If no messages are available, recv
blocks the caller
until a message arrives, unless the socket is set in non-blocking mode.
flags
consists of the following:
MSG_OOB
SO_OOBINLINE
socket option, multiple bytes of data
can be accessed, and the MSG_OOB
option
is not necessary.
MSG_PEEK
recv
call.
read
and recv
behave identically if no flags have been
set for recv
.
recv
succeeds, it returns the length of the
message.
If recv
returns a 0
, it indicates that the connection is closed.
Otherwise, it returns a -1
, and sets errno
to
indicate the type of error. It is possible for recv
to return
fewer bytes than are specified by len
. For example, this
condition
occurs if the number of bytes in an incoming datagram is less than len
. This is not an error.
recv
discards excess bytes if the datagram is larger than the
specified buffer.
recv
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
connect
,
getsockopt
,
recvfrom
,
recvmsg
,
send
,
sendmsg
,
sendto
,
setsockopt
#include <sys/types.h> #include <sys/socket.h> int recvfrom(int s, void *buf, int len, int flags, void *from, int *addrlen);
recvfrom
receives data from an unconnected or connected
socket descriptor s
. If from
is
nonzero,
the source address of the message is
stored in the buffer addressed by from
.
addrlen
is the size of the buffer pointed to by
from
. buf
points to the buffer receiving the message.
len
is the size of the message. recvfrom
is
particularly useful for unconnected datagram sockets.
If no messages are available, recvfrom
blocks the call
until
a message arrives unless the socket is set in non-blocking mode.
flags
consists of the following:
MSG_OOB
SO_OOBINLINE
socket
option, multiple bytes of data can be accessed, and the
MSG_OOB
option is not necessary.
MSG_PEEK
recvfrom
call.
recvfrom
succeeds, it returns the length of the
message.
If recv
returns a 0
, it indicates that the connection is closed.
Otherwise, it returns a -1
, and sets errno
to
indicate the type of error. It is common for recvfrom
to
return fewer than the
total number of bytes in the buffers. This is not an error.
recvfrom
discards excess bytes if a datagram is larger than
the specified buffer.
recvfrom
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
recvfrom
receives a datagram on socket descriptor
s
and places it in buffer in
.
#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #define MAX_DGRAM_SIZE 256 /* Chosen by the application. */ f() { int s; int b; struct sockaddr_in from; /* Sender's address. */ int fromlen; /* Length of sender's address. */ char in[MAX_DGRAM_SIZE] ; /* Open a datagram socket to receive the packet. */ s = socket(AF_INET, SOCK_DGRAM, 0); . . . /* Receive a datagram into the buffer. */ fromlen = sizeof(from); b = (recvfrom(s, in, MAX_DGRAM_SIZE, 0, &from, &fromlen)); if (b == -1) { perror("Recvfrom failed"); return -1; } printf("Datagram size: %d.\n", b); printf("Datagram's IP address is: %s\n", inet_ntoa(from.sin_addr)); printf("Datagram's port is: %d\n", (int) ntohs(from.sin_port)); . . . }
connect
,
getsockopt
,
recv
,
recvmsg
,
send
,
sendmsg
,
sendto
,
setsockopt
#include <sys/types.h> #include <sys/uio.h> #include <sys/socket.h> int recvmsg(int s, struct msghdr *mh, int flags);
recvmsg
receives data from an unconnected or connected
socket descriptor s
. mh
points to a structure that contains
further parameters. The definition of the
msghdr
structure is in
the <sys/socket.h>
header file. The
elements of this structure are as follows:
msg_name
recvmsg
stores the source
address of the message that is being received. This field can be NULL
if the socket s
is connected, or if the
application doesn't require information on the source address.
msg_namelen
msg_name
.
msg_iov
struct iovec
similar to that used
by readv
.
msg_iovlen
msg_iov
.
msg_accrights
AF_INET
.
msg_accrightslen
AF_INET
.
flags
consists of the following:
MSG_OOB
SO_OOBINLINE
socket
option, multiple bytes of data can be accessed, and the
MSG_OOB
option
is not necessary.
MSG_PEEK
recvmsg
call.
recvmsg
succeeds, it returns the length of the
message.
If recv
returns a 0
, it indicates that the connection is closed.
Otherwise, it returns a -1
, and sets errno
to
indicate the type of error. It is possible for recvmsg
to
return fewer bytes than the total number specified by the
iovec
elements. This is not an error.
recvmsg
is an atomic operation. With UDP, no more than one datagram can be
read per call. If you are using datagram sockets, make sure that
there is enough buffer space
in the I/O vector to contain an incoming
datagram.
mh
is commonly documented as struct msghdr mh[]
,
implying that the call operates on an array of these structures. In
reality, only one structure is modified by the call. For the purposes
of clarity, this technical report documents mh
in
a different way, but the implementation is the same. recvmsg
is portable
to other environments, including most UNIX systems, that implement BSD
sockets.
connect
,
getsockopt
,
recv
,
recvfrom
,
send
,
sendmsg
,
sendto
,
setsockopt
#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> void res_init(void);
res_init
initializes the resolver. First,
default options are set. Then, a system configuration file is read if
one can be located. The configuration file may contain default resolver
options for the local site. Refer to Network Administration
for information on default resolver options.
After calling res_init
, the program may override default
site resolver options by accessing the _res
structure described
in The BSD UNIX Socket Library . The program does not need to
call res_init
if _res
values will not be
changed. This routine implements a part of the resolver, which is a
set of routines providing a programming interface for communications
with Internet name servers.
For information on buffer formats for Internet name servers, refer to Chapter 20, "The Domain Name System," in Internetworking with TCP/IP.
res_init
is a direct port from the
BSD UNIX Socket Library.
res_init
is used to initialize the
resolver.
/* Given a hostname as its first parameter, this program prints */ /* the IP address. */ /* Use of the following resolver options is illustrated: */ /* The RES_DEBUG option turns on a resolver trace. */ /* The RES_USEVC option requests use of virtual circuits (TCP) */ /* when contacting the nameserver. */ /* This example assumes that the local site is configured to */ /* use the resolver (instead of a host file). */ /* NOTE: The bitfield(1) compiler option is required. */ #include <sys/types.h> #include <netdb.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> #include <resolv.h> #include <stdio.h> main(int argc, char *argv[]) { struct hostent *hp; struct in_addr ip_addr; /* Host name should be first parameter. */ if (argc <1 || *argv[1] == '\0') exit(EXIT_FAILURE); /* Initialize the resolver, and then set options. */ res_init(); _res.options |= (RES_DEBUG|RES_USEVC); /* When gethostbyname uses the resolver, it uses TCP */ /* and generates a trace. */ hp = gethostbyname(argv[1]); if (!hp) { printf("%s not found\n",argv[1]); exit(EXIT_FAILURE); } /* Host was found. Print its IP address. */ ip_addr = *(struct in_addr *)(hp->h_addr); printf("%s: %s\n",argv[1] ,inet_ntoa(ip_addr)); exit(EXIT_SUCCESS); }
gethostbyaddr
,
gethostbyname
,
gethostent
,
res_send
,
sethostent
#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> int res_mkquery(int op, char *dname, int class, int type, char *data, int datalen, struct rrec *newrr, char *buf, int buflen);
res_mkquery
makes a packet for use with an
Internet domain name
server and places it in the buffer area pointed to by buf
, with
buflen
specifying the length in bytes of the buffer. The
other seven arguments correspond directly to the fields of a
domain name query:
dname
rrec
class
and type
data
datalen
data
.
op
is the specified option.
<arpa/nameser.h>
header file:
QUERY
IQUERY
STATUS
For information on buffer formats for Internet name servers, as well
as
more detailed information about res_mkquery
, refer to
Chapter 20, "The Domain Name System," in
Internetworking with TCP/IP, Volume 1, by Douglas E. Comer, Prentice Hall, 1991.
res_mkquery
returns the size of the query.
It returns a -1
if the size
of the query is greater than buflen
.
res_mkquery
is a direct port from the
BSD UNIX Socket Library.
dn_comp
,
res_init
,
res_send
#include <sys/types.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> int res_send(char *msg, int msglen, char *answer, int anslen);
res_send
sends a query msg
to name servers and returns
an answer. msglen
is the length of the query. answer
is an area where the answer to the query can be stored.
anslen
is the length of the answer buffer.
This routine implements a part of the resolver, which is a set of routines providing a programming interface for communications with Internet name servers.
For information on buffer formats for Internet name servers, refer to Chapter 20, "The Domain Name System," in Internetworking with TCP/IP.
bitfield(1)
option is required for this routine.
res_send
returns the size of the answer.
It returns a -1
if there were errors.
res_send
is a direct port from the
BSD
UNIX Socket Library.
dn_expand
,
res_init
,
res_mkquery
#include <sys/types.h> #include <sys/socket.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
select
checks to see if any sockets are ready for
reading (readfds
), writing (writefds
), or have an
exceptional condition pending (exceptfds
). timeout
specifies the maximum time for select
to complete.
nfds
specifies the maximum number of sockets to check.
If
timeout
is a null pointer, select
blocks
indefinitely. timeout
points to a timeval
structure. A timeout
value of 0
causes select
to return immediately. This behavior is
useful in applications that periodically poll their sockets. The
arrival of out-of-band data is the only possible exceptional
condition. fd_set
is a type defined in the
<sys/types.h>
header file. fd_set
defines a set of file
descriptors on
which select
operates. Passing NULL
for any of the three
fd_set
arguments
specifies that select
should not monitor that condition. On
return, each of the input sets is modified to indicate the subset of
descriptions that are ready. These may be found by using the
FD_ISSET
macro.
The following macros manipulate sets of socket descriptors:
FD_CLR(fd, &fdset)
fd
from the socket descriptor
set fdset
.
FD_ISSET(fd, &fdset)
fd
is a member of
fdset
. Otherwise, it returns a 0
.
FD_SET(fd, &fdset)
fd
to fdset
.
FD_SETSIZE
<sys/types.h>
as the number of socket descriptors
that a process can have open. The default is 64. This value can be
increased before you include <sys/types.h>
. If
FD_SETSIZE
is not increased, the fd_set
structure will not be
defined to be large enough to accommodate socket numbers larger than
63.
FD_ZERO(&fdset)
fdset
to 0
, representing the empty set.
select
succeeds, it returns the number of ready
socket descriptors. select
returns a 0
if the time
limit expires before any sockets are selected. If there is an
error, select
returns
a -1
.
For non-integrated sockets, the
SAS/C Library blocks all asynchronous
signals during routines that call the TCP/IP communications
software.
Thus,
calls to select
may leave asynchronous signals blocked for
long periods of time.
For integrated sockets, select
may be interrupted by any
unblocked signal, either managed by OpenEdition or SAS/C, in which
case select
will return -1
, and errno will be set to EINTR
.
select
is portable to other environments, including
most UNIX systems, that implement BSD
sockets.
Unlike UNIX, the SAS/C implementation of select
does not
apply to
files,
unless you are using integrated sockets.
Even if you are using integrated sockets, select has no effect on
any non-HFS file descriptors specified.
In addition,
select
cannot be used in conjunction with asynchronous I/O,
because asynchronous I/O is not supported by the SAS/C Compiler.
select
waits for data to read from a
socket.
#include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <stdio.h> /* This function calls select to wait for data to read from */ /* one of the sockets passed as a parameter. */ /* If more than 3 seconds elapses, it returns. */ /* Return value flags. These indicate the readiness of */ /* each socket for read. */ #define S1READY 0x01 #define S2READY 0X02 waittoread(int s1,int s2) { fd_set fds; struct timeval timeout; int rc, result; /* Set time limit. */ timeout.tv_sec = 3; timeout.tv_usec = 0; /* Create a descriptor set containing our two sockets. */ FD_ZERO(&fds); FD_SET(s1, &fds); FD_SET(s2, &fds); rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); if (rc==-1) { perror("select failed"); return -1; } result = 0; if (FD_ISSET(s1, &fds)) result |= S1READY; if (FD_ISSET(s2, &fds)) result |= S2READY; return result; }
connect
,
read
,
recv
,
send
,
write
#include <sys/types.h> #include <sys/socket.h> #include <lcsignal.h> int selectecb(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout, struct _ecblist *ecblist, size_t ecblcnt)
selectecb
is identical to select
with the
exception that,
in addition to returning when the timeout expires or when activity
occurs on one of the specified sockets, selectecb
also
returns if one of the specified ECBs (Event Control Blocks) is
posted.
The ecblist
argument is the address of an array of
structures, each of which
represents one or more contiguous ECBs. Each structure
contains two members, a count of the number
of ECBs, and the address of an array of ECBs. The count may
be 0
, in which case the ECB array address is ignored.
The declaration for the _ecblist
structure is as follows:
struct _ecblist { size_t count; unsigned *ecbarr; }The ECB list is passed via the struct
_ecblist
for
several reasons. It allows a static ECB list to be used in many
cases, since individual ECBs can easily be removed by setting
their
count
member to 0
.
For applications that have a large number of ECBs,
_ecblist
facilitates organizing them into arrays; this may
slightly improve
the performance of selectecb
, since fewer memory
accesses are required to determine the addresses of all the ECBs.
Note that an ECB may be POSTed at any time. Thus, you cannot
assume that no ECBs have been POSTed when selectecb
returns
with one or more socket descriptor bits set. An ECB may have
been POSTed between the time that selectecb
was returning
and the time that your program checked the return code from
selectecb
.
If ecblist
is NULL
, or ecblcnt
is 0
, or the
count
field of all the
_ecblist
structures is set to 0
, ECB waiting is not
used
and the effect is exactly the same as if select
had been
called.
selectecb
may leave asynchronous signals blocked for
long periods of time.
For non-integrated sockets, the SAS/C Library blocks all asynchronous signals during routines that call the TCP/IP communications software.
For integrated sockets, selectecb
may be interrupted by any
unblocked signal, either managed by OpenEdition or SAS/C, in which
case selectecb
will return -1
, and errno will be set to EINTR
.
However,
execution of selectecb
is not interrupted by an OpenEdition signal
unless the signal terminates the process.
#include <sys/types.h> #include <sys/socket.h> int send(int s, const void *buf, int len, int flags);
send
transmits a message to socket descriptor s
. The
socket
must
be connected or associated with a foreign peer via the connect
function.
buf
points to the buffer that contains the message.
len
is the number of bytes to be sent.
flags
consists of the following:
MSG_OOB
MSG_DONTROUTE
send
succeeds, it returns the number of characters sent.
If there is an error, it returns a -1
.
send
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
recv
,
recvfrom
,
recvmsg
,
sendmsg
,
sendto
,
write
#include <sys/types.h> #include <sys/socket.h> int sendmsg(int s, struct msghdr *mh, int flags)
sendmsg
sends a message to an unconnected or connected
socket s
. mh
points to a structure containing
further parameters.
The definition of the
msghdr
structure is in the
<sys/socket.h>
header file. The
elements of this structure are as follows:
msg_name
sendmsg
stores the
source address of the message that is being received. This field can be
NULL
if the socket s
is connected, or if the
application doesn't require information on the source address.
msg_namelen
msg_name
.
msg_iov
struct iovec
similar to that used
by readv
.
msg_iovlen
msg_iov
.
msg_accrights
AF_INET
.
msg_accrightslen
AF_INET
.
flags
consists of the following:
MSG_OOB
MSG_DONTROUTE
sendmsg
succeeds, it returns the length of the
message. Otherwise, it returns a -1
, and sets errno
to
indicate the type of error.
sendmsg
is an atomic operation. With UDP, no more than one datagram can be
read per call. If you are using datagram sockets, make sure that
there is enough buffer space
in the I/O vector to contain an incoming
datagram.
mh
is commonly documented as struct msghdr mh[]
,
implying that the call operates on an array of these structures. In
reality, only one structure is modified by the call. For the purposes
of clarity, this manual documents mh
in a different way, but the implementation is the same.
sendmsg
is portable
to other environments, including most UNIX systems, that implement BSD
sockets.
sendmsg
is used to transmit banking
transactions.
#include <sys/types.h> #include <sys/uio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include "transdef.h" /* application header file */ /* This routine writes banking transactions to one of several */ /* regional servers (chosen based on the contents of the transaction, */ /* not based on the location of the local host). "s" is a datagram */ /* socket. "head" and "trail" are application level transaction */ /* header and trailer components. "trans" is the body of the */ /* transaction. Reliability must be ensured by the caller (because */ /* datagrams do not provide it). The server receives all three */ /* parts as a single datagram. */ puttrans(int s, struct header *head, struct record *trans, struct trailer *trail) { int rc; /* socket address for server */ struct sockaddr_in dest; /* will contain information about the remote host */ struct hostent *host; char fullname[64]; /* Will point to the segments of the (noncontiguous) */ /* outgoing message. */ struct iovec iov[3]; /* This structure contains parameter information for sendmsg. */ struct msghdr mh; /* Choose destination host from region field of the data */ /* header. Then find its IP address. */ strcpy(fullname,head->region); strcat(fullname,".mis.bank1.com"); host = gethostbyname(fullname); if (host==NULL) { printf("Host %s is unknown.\n",fullname); return -1; } /* Fill in socket address for the server. We assume a */ /* standard port is used. */ memset(&dest,'\0',sizeof(dest)); dest.sin_family = AF_INET; memcpy(&dest.sin_addr,host->h_addr,sizeof(dest.sin_addr)); dest.sin_port = htons(TRANSACTION_SERVER); /* Specify the components of the message in an "iovec". */ iov[0] .iov_base = (caddr_t)head; iov[0] .iov_len = sizeof(struct header); iov[1] .iov_base = (caddr_t)trans; iov[1] .iov_len = sizeof(struct record); iov[2] .iov_base = (caddr_t)trail; iov[2] .iov_len = sizeof(struct trailer); /* The message header contains parameters for sendmsg. */ mh.msg_name = (caddr_t) &dest; mh.msg_namelen = sizeof(dest); mh.msg_iov = iov; mh.msg_iovlen = 3; mh.msg_accrights = NULL; /* irrelevant to AF_INET */ mh.msg_accrightslen = 0; /* irrelevant to AF_INET */ rc = sendmsg(s, &mh, 0); /* no flags used */ if (rc == -1) { perror("sendmsg failed"); return -1; } return 0; }
connect
,
getsockopt
,
ioctl
,
recv
,
recvfrom
,
recvmsg
,
send
,
sendto
,
setsockopt
#include <sys/types.h> #include <sys/socket.h> int sendto(int s, const void *buf, int len, int flags, const void *to, int addrlen);
sendto
transmits a message from the area pointed to by
buf
of length len
to
socket descriptor
s
. to
is the target address; addrlen
is the
address size. sendto
can be used on any type of socket. It is
most commonly used
for unconnected datagram sockets for which different destinations may
be associated with different datagrams.
flags
consists of the following:
MSG_OOB
MSG_DONTROUTE
sendto
succeeds, it returns the number of characters sent.
If there is an
error, it returns a -1
.
sendto
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
recv
,
recvfrom
,
recvmsg
,
send
,
sendmsg
,
write
#include <netdb.h> void sethostent(int stayopen);
sethostent
opens a host file or begins a connection with the
name server.
In some instances, when the resolver is used to look up the
host name,
a virtual
circuit (that is,
a TCP connection) is used to communicate with the
name server. This is based on the RESOLVEVIA
statement in the
TCPIP.DATA
file
or the RES_USEVC
resolver
option specified by your program. In
these cases, you can use the RES_STAYOPEN
resolver
option to maintain the
connection with the name server between queries.
In other instances, the host file is used as a source of host
names. In this case, sethostent
rewinds the file. This
enables successive sethostent
calls to read the host file
sequentially. Specifying the stayopen
parameter with
sethostent
causes the host file to remain open between
gethostbyname
and gethostbyaddr
calls.
Refer to Network Administration for information on naming host files and the logic that determines whether the host file or the resolver is used for looking up names.
sethostent
does not return a value.
sethostent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
sethostent
is a combination of the
host file and resolver versions of the BSD UNIX Socket
Library sethostent
.
endhostent
,
gethostent
,
gethostbyname
#include <netdb.h> void setnetent(int stayopen);
setnetent
opens the
network file, that is, a file with the same format as
/etc/networks
in the UNIX environment. If the file is already open,
setnetent
rewinds the file so that succeeding getnetent
calls can read it sequentially. Specifying a nonzero value
for stayopen
causes the network file to remain open
between subsequent getnetbyname
and getnetbyaddr
calls. Refer to Network Administration
for
information on naming the network file for your system.
setnetent
does not return a value.
setnetent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getnetent
,
endnetent
,
getnetbyname
,
getnetbyaddr
#include <netdb.h> void setprotoent(int stayopen);
setprotoent
opens the
protocols file, that is, a file with the same format as
/etc/protocols
in the UNIX environment. If the file is already open,
setprotoent
rewinds the file so that succeeding
getprotoent
calls can read it sequentially. Specifying a nonzero value
for stayopen
causes the protocols file to remain open
between subsequent getprotobyname
and
getprotobynumber
calls. Refer to Network Administration
for
information on naming the protocols file for your system.
setprotoent
does not return a value.
setprotoent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
endprotoent
,
getprotobyname
,
getprotobynumber
,
getprotoent
/etc/rpc
Protocols File#include <netdb.h> int setrpcent(int stayopen);
setrpcent
opens the Sun RPC program numbers
file, that is, a file with the same
format as /etc/rpc
in the UNIX environment. If the file is already
open, setrpcent
rewinds the file so that succeeding getrpcent
calls can read it sequentially. Specifying a nonzero value for
stayopen
causes the protocols file to remain open between subsequent
getrpcbyname
and getrpcbynumber
calls. Refer to
/etc/rpc
and Network Administration
for information on naming
this file for your system.
setrpcent
does not return a value.
getrpcbynumber
returns points to a static structure
within the library. You must copy the information from this structure
before you make further getrpcbyname
, getrpcbynumber
, or
getrpcent
calls.
setrpcent
is portable to other systems that support Sun RPC 4.0.
endrpcent
, getrpcbyname
,
getrpcbynumber
, getrpcent
#include <netdb.h> void setservent(int stayopen);
setservent
opens the
services file, that is, a file with the same format as
/etc/services
in the UNIX environment. If the file is already open,
setservent
rewinds the file so that succeeding
getservent
calls can read it sequentially. Specifying a nonzero value
for stayopen
causes the protocols file to remain open
between subsequent getservbyname
and
getservbyaddr
calls. Refer to Network Administration for
information on naming the services file for your system.
setservent
does not return a value.
setservent
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
getservent
,
endservent
,
getservbyname
,
getservbyport
#include <sys/types.h> #include <sys/socket.h> int setsockimp(const char *name);
setsockimp
defines the name of the socket implementation.
It must be
called before calling any other socket function. The argument
name
is
a one-to-four character string identifying the socket implementation.
If name is "COM"
, the standard non-integrated socket implementation
at your site is used. If name is "OE"
,
the OpenEdition integrated
socket implementation is used. Your TCP/IP vendor may define other
names to access a specific implementation. The name string is used to
construct the name of a load module (LSCNname) implementing the
socket interface.
If setsockimp
is not called before socket functions are used, a
default socket implementation is used. For programs invoked with
exec
-linkage, the default implementation is OpenEdition integrated
sockets. For other programs, the default is non-integrated sockets.
setsockimp
returns 0
if successful or -1
if unsuccessful. If
setsockimp
fails because an invalid implementation name was specified,
socket functions can still be called, and the default implementation
will be used.
#include <sys/types.h> #include <sys/socket.h> int setsockopt(int s, int level, int optname, const void *optval, int optlen);
setsockopt
sets the value of the options associated with
socket descriptor
s
. level
is the level of the option.
optname
is the name of the option. optval
is a
pointer to a buffer that receives the value of the
requested option.
As an input parameter, the integer optlen
should
be set to the size of the optval
buffer.
Most options are at the socket level. Pass SOL_SOCKET
as the
level
parameter for these options:
SO_LINGER
linger
option.
The linger
option controls the behavior of the close
call when there
are some data that have not been sent. optval
should point to
a struct linger
. If the value of the l_onoff
field
is 0
, close
returns immediately. In this case, TCP/IP continues to
attempt to deliver the data, but the program is not informed if
delivery fails. If the value of the l_onoff
field is
nonzero, the behavior of the close
call depends on the value of
the l_linger
field. If this value is 0
, unsent
data are discarded at the time of the close
.
If the value of l_linger
is
not 0
, the close
call blocks the caller until there is a
timeout or until all data are sent. The l_linger
field
indicates the length of the desired timeout period. Some TCP/IP
implementations may ignore the value of the l_linger
field.
s
must be a stream socket.
SO_OOBINLINE
MSG_OOB
flag in
recv
calls. optval
should point to an integer.
s
must be a stream socket. Refer to "Out-of-Band Data"
in Chapter 6, "Berkeley Sockets," in UNIX Network Programming for information
on out-of-band data.
SO_REUSEADDR
optval
should
point to an integer.
s
must be a stream socket.
IPPROTO_TCP
is available for one option. The
TCP_NODELAY
option indicates that TCP's normal socket buffering
should not be used on the socket. The TCP_NODELAY
option is not
operative; it
is supported for source code compatibility. The
<netinet/in.h>
and <netinet/tcp.h>
headers files are required for this
option.
setsockopt
succeeds, it returns a 0
. Otherwise,
it returns a -1
, and sets errno
to
indicate the type of error.
setsockopt
is portable to other environments, including most
UNIX systems, that implement BSD
sockets. The supported options may vary depending on the system;
additional
options may be supported by a specific TCP/IP software
product, and the
options described above may be supported differently. Refer to your
software documentation for details.
bind
,
close
,
ioctl
,
recv
,
socket
#include <sys/types.h> #include <sys/socket.h> int shutdown(int s, int how);
shutdown
ends communication on socket descriptor s
in
one or both directions.
how
specifies the shutdown condition and can be specified in
the following ways:
0
1
2
shutdown
is successful, it returns a 0
; otherwise, it
returns a -1
, and sets errno
to
indicate the type of error.
shutdown
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
close
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol);
socket
creates an endpoint for communication and returns a
descriptor, which is a small integer used to reference the socket.
domain
<sys/socket.h>
header file. The defined families
are as follows:
AF_INET
AF_UNIX
type
<sys/socket.h>
. The defined types are as follows:
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
connect
call
before any data can be sent or received on it. Data are
transferred
using read
or write
calls or variants of the
send
and receive
calls. The socket can be
closed with a close
call when the session is completed, or
the socket will be closed automatically at program exit.
protocol
protocol
is set to 0
, the
system selects the default protocol number for the socket domain and
type specified. This is usually adequate, since the most common
socket types support
only one protocol. getprotobyname
and related calls can also
be used to select the protocol.
socket
is successful, it returns a descriptor referencing
the socket; otherwise, it
returns a -1
, and sets errno
to
indicate the type of error.
socket
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
/* This is an example of a complete socket program. It is a */ /* client program for the finger server which runs on many UNIX */ /* systems. This client program returns information about logged */ /* on users for any remote system that is running the finger */ /* server. The format of the command is: */ /* */ /* finger [-l] hostname */ /* */ /* The output is typically identical to that which one would */ /* receive when running the "finger" command locally on that */ /* system. Specification of the -l option results in more */ /* verbose output. */ #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include <fcntl.h> /* No need to translate characters on ASCII systems. */ #ifndef __SASC__ #define ntohcs(c) (c) #define htoncs(c) (c) #endif /* Define some useful constants. */ #define FALSE 0 #define TRUE 1 #define READ_BLOCK_SIZE 256 #define OUTBUF_SIZE 2 #define FINGER_PORT 79 #define ASCII_CR 0x0D #define ASCII_LF 0x0A main(int argc, char *argv[]) { int n,i; /* Socket descriptor for communication with the finger server.*/ int s; /* Socket address for server. */ struct sockaddr_in sa; /* Use to send ASCII CR and LF characters required by */ /* the protocol. */ char cr = ASCII_CR, lf = ASCII_LF; /* buffers */ char in[READ_BLOCK_SIZE] ; char out[OUTBUF_SIZE] ; /* option status */ int longlist = FALSE; char *op; /* will contain information about the finger service */ struct servent *serv; /* will contain information about the remote host */ struct hostent *host; if (*++argv && *argv[0] == '-') { /* argument processing */ op = *argv; if (op[1] == 'l' || op[1] == 'L') longlist = 1; else printf("finger: unsupported option \ "%c\"",op[1]) argv++; } if (!*argv) { printf("finger: hostname missing"); exit(EXIT_FAILURE); } /* Assume *argv now points to hostname. */ /* Find the IP address for the requested host. */ host = gethostbyname(*argv); if (host==NULL) { printf("finger: Host %s is unknown.\n",*argv ); exit(EXIT_FAILURE); } /* Find the port for the finger service. If the services file */ /* is not available, we will use the standard number. We */ /* specify "tcp" as the protocol. This call attempts to */ /* find the services file. */ serv = getservbyname("finger", "tcp"); /* Prepare a socket address for the server. We need an IP */ /* address(corresponding to the given host name) and a port */ /* number (corresponding to the "finger" service). */ memset(&sa,'\0',sizeof(sa)); sa.sin_family = AF_INET; memcpy(&sa.sin_addr,host->h_addr,sizeof(sa.sin_addr)); sa.sin_port = serv ? serv->s_port : htons(FINGER_PORT); /* Get a socket of the proper type. We use SOCK_STREAM */ /* because we want to communicate using TCP (we want a */ /* reliable protocol). */ s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) { perror("finger - socket() failed"); exit(EXIT_FAILURE); } /* Connect to the host and port. */ if (connect(s, &sa, sizeof(sa)) == -1) { perror("finger - connect() failed"); return(EXIT_FAILURE); } /* read() and write() are the most convenient calls for */ /* transmitting and receiving data over stream sockets. */ /* Write to server. */ /* If long option is specified, pass that first. */ if (longlist) { out[0] = htoncs('/'); out[1] = htoncs('W'); write(s,out,2); } /* Terminate msg with CR-LF. */ write(s,&cr,1); write(s,&lf,1); /* Server should respond. */ /* Read until EOF indicated. */ while (n=read(s,in,READ_BLOCK_SIZE)) { for (i=0; i<n ; i++) { if (in[i] ==ASCII_CR) continue; /* Presume part of CR-LF pair. */ putchar(ntohcs(in[i] )); } } /* Close the socket. */ close(s); }
accept
,
bind
,
close
connect
,
getsockname
,
getsockopt
,
givesocket
,
listen
,
open
,
read
,
recv
,
recvfrom
,
recvmsg
,
select
,
send
,
sendmsg
,
sendto
,
setsockopt
,
shutdown
,
takesocket
,
write
,
writev
#include <sys/types.h> #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int fd[2]);
socketpair
creates a connected pair of unnamed sockets.
The arguments are:
domain
AF_UNIX
must be
specified.
type
SOCK_STREAM
or SOCK_DGRAM
may be specified.
protocol
p_proto
field of the protoent
structure. If a 0
is specified, the system will select the protocol.
Refer to The BSD UNIX Socket Library for information about
the protoent
structure.
fd
socketpair
is successful, it returns 0
; otherwise,
it returns a - 1
and sets errno
to indicate the type of
error.
socketpair
is only vaild when integrated sockets are
in use.
socketpair
is portable to other environments, including
most UNIX systems that implement BSD sockets.
#include <sys/types.h> #include <sys/socket.h> void socktrm(void)
socktrm
terminates the current SAS/C Socket Library
environment and
returns it to an uninitialized state without requiring termination
of the general SAS/C Library environment.
For integrated sockets, calling socktrm
has no effect since
socket status is controlled by OpenEdition rather than by the
SAS/C Library. Any open sockets remain open.
For CICS sockets, the effect of calling socktrm
is to close all
open socket connections and mark the socket library state as
uninitialized. For CICS, since no IBM TCP/IP CICS call is provided
to directly undo the libraries', internal CICS socket initialization
INITAPI call, further socket calls by the application may result in
errors indicating that a second INITAPI was attempted with a
duplicate name. Note that the current IBM CICS
TCP/IP behavior is to free up the name for reuse after a duplicate
INITAPI is attempted; however, the library does not take
advantage
of this behavior.
socktrm
is specific to the SAS/C
sockets implementation for use with
IBM TCP/IP and, therefore, is not portable. Other TCP/IP vendors and
socket implementations, at their discretion, may provide
an equivalent function call or different functionality.
close
, shutdown
#include <sys/types.h> #include <sys/socket.h> int takesocket(struct clientid *clientid, int s);
takesocket
takes a socket descriptor, s
, and a pointer to
a client structure, clientid
, and returns a local client socket
descriptor, which must be used for subsequent TCP/IP calls. s
must be a connected stream socket. The donor process must have already
obtained client ID for the receiving process, and must have already
called givesocket
. The mechanism for exchanging client IDs and
the socket descriptor number is the responsibility of the two processes
and is not accomplished by either the givesocket
or the
takesocket
call.
When giving a socket, the donor may use a clientid
structure
that contains blanks as the subtask name. However, when taking
a socket, the receiver must
specify the subtask name of the donor in the client ID. This allows
the donor to make the socket available to any number of subtasks while
the receiver must have the actual subtask name to take the socket.
The subtask name effectively acts as a key.
The donor process should not close the socket before the receiving
process has completed the takesocket
call. The receiving
process must have a means of informing the donor that the
takesocket
call has completed. Using
select
or selectecb
in the donor, frees the
receiver of this responsiblility.
Note:
takesocket
is only supported with non-integrated sockets.
takesocket
is successful, it returns a non-negative,
client socket descriptor, which can be different from the donor
descriptor, s
. Otherwise, it returns a - 1
, and sets
errno
to indicate the type of error.
takesocket
is not portable to UNIX operating systems.
On UNIX operating systems, sockets are typically transferred from
parent to child processes as a side effect of the fork()
system call.
getclientid
function for an
example that illustrates the use of takesocket
.
getclientid
,
givesocket
#include <sys/types.h> #include <sys/uio.h> #include <fcntl.h> int writev(int s, struct iovec *iov, int iovcnt);
writev
writes data to connected socket descriptor s
from
the iovcnt
buffers specified by the iov
array. As with the
write
call, the socket must have been previously
associated with a remote address via the connect
system call.
If there are no data, writev
blocks the caller
unless the socket is in non-blocking mode. The iovec
structure is defined in the
<sys/uio.h>
header file. Each iovec
entry specifies
the base address and length of an area in memory from which the data
should be taken. writev
completely sends one area
before proceeding to the next area.
writev
is an atomic operation. For datagram sockets, each
writev
call causes one datagram to be sent.
Note:
Although writev
is primarily used
with sockets, it can also be used to write any file that can be
accessed by the write
function.
writev
succeeds, it returns the number of bytes written.
If writev
returns a 0
, the end-of-file has
been reached. If writev
fails, it
returns a -1
.
writev
is portable to other environments, including most
UNIX systems, that implement BSD
sockets.
connect
,
recv
,
recvfrom
,
recvmsg
,
read
,
readv
,
write
Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.