Chapter Contents

Previous

Next
accept

accept



Accepts a Connection Request

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.