#include <stdio.h> 
#include <errno.h> 
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


/*** Server Side of the code ***/ 
int server() 	
{
	   int f;
	   struct sockaddr_in from;
	   struct sockaddr_in  sin;
	   const int on = 1;
	   
	   /* Restricted port--see section 5 */
memset( &sin, 0, sizeof sin );
		sin.sin_addr.s_addr = inet_addr("127.0.0.1");
 	    sin.sin_family = AF_INET; 
		sin.sin_port = htons(2999);
		sin.sin_len   = sizeof(sin);
		printf("server port =%08x %08x %08x\n", sin.sin_port, htons(2999), 2999);
		printf("Server Scok1 p=%08x a=%08x\n", sin.sin_port, sin.sin_addr.s_addr);
	   f = socket(AF_INET, SOCK_STREAM, 0);
	   
	   
	   printf("Server Scok2 p=%08x a=%08x\n", sin.sin_port, sin.sin_addr.s_addr);
	   
	   if  (bind(f,  (struct  sockaddr  *)  &sin,  
	        sizeof (sin)) < 0) {
	        printf("Sockect bind failed\n");
	   }

	   if(setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)))
	   		printf("setsockopt failed\n");
	   
	   listen(f, 0);
	   for (;;) {
	       int g, len = sizeof (from);

	       g =  accept(f, (struct  sockaddr *)  &from, &len);
	       printf("Server Scok3 p=%08x a=%08x\n", from.sin_port, from.sin_addr.s_addr);

	       if (g < 0) {
	    	   printf("g=%d\n", g);
	           if (errno != EINTR)
	               printf("accept failed with errno = %d p=%d a=%08x\n", errno, from.sin_port, from.sin_addr.s_addr);
	           continue;
	       }
	       if (fork() == 0) {
	           close(f);	           
/* Handle the client request in separate process */
break;
	       }
	       close(g);
	   }
   return EXIT_SUCCESS; 
} 

/*** Client Side of the code ***/ 
int client(const char * addr, unsigned short port) { 
	   struct sockaddr_in server;
	   struct sockaddr_in sin;
	   int s;
       
       memset( (char *)&server, 0, sizeof (server));
       server.sin_addr.s_addr = inet_addr(addr); 
       printf("server address =%08x\n", server.sin_addr.s_addr);
       server.sin_family =  AF_INET;
       server.sin_port = htons(port);
       printf("server port =%08x %08x %08x\n", server.sin_port, htons(port), port);
       server.sin_len  = sizeof(server);
       
       sin.sin_family =  AF_INET;
       sin.sin_port	= 0;
       s = socket(AF_INET, SOCK_STREAM, 0);
       if (s < 0) {
              perror("socket stream failed");
              exit(3);
       }
       if  (bind(s,  (struct  sockaddr  *)  &sin,  
       	        sizeof (sin)) < 0) {
       	        printf("Sockect bind failed\n");
       	   }
       /* Connect does the bind() for us */

       if (connect(s, (const struct sockaddr *)&server, sizeof (server)) < 0) {
              perror("rlogin: connect");
              exit(5);
       }

return EXIT_SUCCESS; 
} 

int main(int argc, char **argv) { 
int ret; 

if (argc < 2) { 
printf("Usage %s -s | -c \n", argv[0]); 
ret = EXIT_FAILURE; 
} 
else if (strcmp(argv[1], "-c") == 0) 
{ 
	//printf("Running Client... %s %d\n", argv[2], (unsigned short)atoi(argv[3])); 
	//ret = client(argv[2], (unsigned short)atoi(argv[3])); /* see name_open() for this code */
	printf("Running Client... \n");
	ret = client("127.0.0.1", 2999); /* see name_open() for this code */
} 
else if (strcmp(argv[1], "-s") == 0) { 
printf("Running Server ... \n"); 
ret = server(); /* see name_attach() for this code */ 
} 
else { 
printf("Usage %s -s | -c \n", argv[0]); 
ret = EXIT_FAILURE; 
} 
return ret; 
} 
