Chapter Contents |
Previous |
Next |
accept |
Portability: | UNIX compatible |
SYNOPSIS | |
DESCRIPTION | |
RETURN VALUE | |
PORTABILITY | |
EXAMPLE | |
RELATED FUNCTIONS |
SYNOPSIS |
#include <sys/types.h> #include <sys/socket.h> int accept(int s, void *addr, int *addrlen);
DESCRIPTION |
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.
RETURN VALUE |
If
accept
is successful, it returns a nonnegative value that is the descriptor
of the newly created socket. Otherwise, it returns a
-1
.
PORTABILITY |
accept
is portable to other environments, including UNIX systems, that
implement BSD sockets.
EXAMPLE |
In the following example,
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. */ }
RELATED FUNCTIONS |
bind
,
connect
,
listen
,
select
,
socket
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.