/* server.c - code for example server program that uses TCP */

#ifndef unix
#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>

#define PROTOPORT 5193 /* default protocol port number */
#define QLEN 6 /* size of request queue */
int visits = 0; /* counts client connections */
/*-----------------------------------------------------------------
* Program: server
* Purpose: allocate a socket and then repeatedly execute the following:
* (1) wait for the next connection from a client
* (2) send a short message to the client
* (3) close the connection
* (4) go back to step (1)
* Syntax: server [ port ]
* port - protocol port number to use
* Note: The port argument is optional. If no port is specified,
* the server uses the default given by PROTOPORT.
*-------------------------------------------------------------------
*/

main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold server's address */
struct sockaddr_in cad; /* structure to hold client's address */
int sd, sd2; /* socket descriptors */
int port; /* protocol port number */
int alen; /* length of address */
char buf[1000]; /* buffer for string the server sends */

#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif

memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
/******* BEGIN PREPARING OWN ADDRESS STRUCTURE *********/
/*Step-1: Set protocol family*/
sad.sin_family = AF_INET;

/*Step-2: Set the local IP address. Willing to receive in any IP address of the host */
sad.sin_addr.s_addr = INADDR_ANY;

/*Step-3: Set protocol port number*/
/* Check command-line argument for protocol port and extract */
/* port number if one is specified. Otherwise, use the default */
/* port value given by constant PROTOPORT */
if (argc > 1) { /* if argument specified */
port = atoi(argv[1]); /* convert argument to binary */
} else {
port = PROTOPORT; /* use default port number */
}

if (port > 0) /* test for illegal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s\n",argv[1]);
exit(1);
}
/******* OWN ADDRESS STRUCTURE PREPARED *********/
 

/* Map TCP transport protocol name to protocol number */
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map \"tcp\" to protocol number");
exit(1);

}

/* Create a socket */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);

}

/* Bind a local address to the socket */
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"bind failed\n");
exit(1);
}

/* Specify size of request queue */
if (listen(sd, QLEN) < 0) {
fprintf(stderr,"listen failed\n");
exit(1);
}

/* Main server loop - accept and handle requests */
while (1) {
    alen = sizeof(cad);
    if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
        fprintf(stderr, "accept failed\n");
        exit(1);
    }

    visits++;
    sprintf(buf,"This server has been
    contacted %d time%s\n",visits,visits==1?".":"s.");
    send(sd2,buf,strlen(buf),0);
    closesocket(sd2);

}

}