#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/time.h>
#include<arpa/inet.h>

int main(int argc,char *argv[])
{

  struct sockaddr_in saddr,caddr;
  int sock,newsock,newsock1;
  int test,count;
  fd_set readset,testset,testset1;
  char buf[100],buf1[100],info[100];
  struct timeval newtimer;
  struct timeval newtime;
  struct timeval newtimer1;
  struct timeval timer;
  timer.tv_sec=25;
  newtime.tv_sec=10;
  newtimer1.tv_sec=15;
  sock=socket(AF_INET,SOCK_STREAM,0); 
  bzero(&saddr,sizeof(saddr));
  saddr.sin_family=AF_INET;
  saddr.sin_port=htons(atoi(argv[1]));
  saddr.sin_addr.s_addr=htonl(INADDR_ANY);       

 if( bind(sock,(struct sockaddr*)&saddr,sizeof(saddr))<0)
   {
   printf("bind error");
   exit(1);
   }
  listen(sock,5);

  int clength=sizeof(caddr);
 
  int a;
  
  while(1)
  {
  printf("\n SERVER WAITING FOR NEW PAIRS OF CONNECTION\n"); 
  FD_ZERO(&readset); 
  FD_SET(sock,&readset);
  testset1=readset;
  newsock=accept(sock,NULL,NULL);
  recv(newsock,info,sizeof(info),0);
  printf("\nSERVER WILL ACCEPT CONNECTION ONLY FROM : ");
  printf("%s",info);
  FD_SET(newsock,&readset);  
   printf("\n\nTHE SERVER WILL WAIT FOR 25 SECONDS FOR THE OTHER CLIENT");
   fflush(stdout);

   
   fflush(stdout);
   if(( count= select(FD_SETSIZE,&testset1,NULL,NULL,&timer))>0)
   { 
     
    if(FD_ISSET(sock,&testset1))
    {
     newsock1=accept(sock,(struct sockaddr*)&caddr,(socklen_t*)&clength);
     if(strcmp((inet_ntoa(caddr.sin_addr)),info)==0)
     {
     FD_SET(newsock1,&readset); 
     test=1;
     } 
     else 
     {
      printf("\n\nWRONG CONNECTION \n");
      send(newsock,"quit\n",10,0);
      send(newsock1,"server busy",15,0);
      close(newsock1);
     }       
    }
    }
    else if(count ==0) 
    {
      send(newsock,"quit\n",10,0);
      printf("\n\nTIME OUT\n");
      fflush(stdout);
      close(newsock);
     }
   
  
  FD_SET(newsock,&readset);
  FD_SET(newsock1,&readset);
  FD_SET(sock,&readset);
  bzero(&buf,sizeof(buf));
  bzero(&buf1,sizeof(buf1));
  while(test)
  {
    int x=newsock;
    int y=newsock1;
    testset=readset;
    select(FD_SETSIZE,&testset,NULL,NULL,NULL);
     if(FD_ISSET(sock,&testset))
      {
        int third = accept(sock,NULL,NULL);
        send(third,"server busy",15,0);
        close(third);
       }    
   
    else if(FD_ISSET(x,&testset))
     {

      int nread= recv(newsock,buf,sizeof(buf),0);
      buf[nread]='\0';
      if(strcmp(buf,"quit\n")==0)
      {
       printf("\nCLIENTS TERMINATED\n");
       send(newsock1,buf,sizeof(buf),0);
       send(newsock,buf,sizeof(buf),0);
       close(newsock);
       close(newsock1); 
       test=0;      
       FD_CLR(x,&testset);
       FD_CLR(newsock,&readset);
      
      }
      else
      {
      
      send(newsock1,buf,strlen(buf),0);
      bzero(&buf,sizeof(buf));
      FD_CLR(x,&testset);
      }
     }
      else if(FD_ISSET(y,&testset))
     {
       int man=recv(newsock1,buf1,sizeof(buf1),0);
       buf1[man]='\0';
       if(strcmp(buf1,"quit\n")==0)
       {
         printf("\n CLIENT TERMINATED\n");
         send(newsock,buf1,sizeof(buf1),0);
         send(newsock1,buf1,sizeof(buf1),0);
         close(newsock1);
         close(newsock); 
         test=0;
         FD_CLR(y,&testset);
         FD_CLR(newsock1,&readset);
         
       }  
       else
       {        
       send(newsock,buf1,strlen(buf1),0);
       bzero(&buf1,sizeof(buf1));
       FD_CLR(y,&testset);
       }
      } 
     }
   }
 return 0;
  }


 


