#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include "stdio.h"     
#include "stdlib.h"
#include "unistd.h" 

#define max_clients 10


int CreateSocket(int Porta)
{
  int sock,errore;
  struct sockaddr_in temp;

  //Socket creation
  sock=socket(AF_INET,SOCK_STREAM,0);
  temp.sin_family=AF_INET;
  temp.sin_addr.s_addr=INADDR_ANY;
  temp.sin_port=htons(Porta);

  //No blocking socket
  errore=fcntl(sock,F_SETFL,O_NONBLOCK);

  //Bind socket
  errore=bind(sock,(struct sockaddr*) &temp,sizeof(temp));

  //Number of client allowed
  errore=listen(sock,max_clients);
 
  return sock;
}

void CloseSocket(int sock)
{
  close(sock);
  return;
}

int main()
{


  
  //Connected clients
  int connected = 0;
  
  int sockets[max_clients];
  int sockets_s[max_clients];
  int ProcessingSock = 0;
  
  //Reading Buffer
  unsigned char  buffer[512];
  
  //Socket Main
  int DescrittoreSocket;

   //Number of received bytes
  int Quanti;
  
    //Socket reset
	for ( ProcessingSock = 0; ProcessingSock < max_clients; ProcessingSock++)
	{
	sockets_s[ProcessingSock] = 0;
	}

  //Socket main creator
  DescrittoreSocket=CreateSocket(502);
  
  
  printf("Server: Waiting for clients...\n");
  printf("Server: Clients connected:%d\n", connected);
  
  
  
while (1)
{
  


  //Delay
  usleep(100);
  
	for ( ProcessingSock = 0; ProcessingSock < max_clients; ProcessingSock++)
	{
	
	
	if ( sockets_s[ProcessingSock] == 0 )
	{
	
    //Wait for sockets
    if ((sockets[ProcessingSock]=accept(DescrittoreSocket,0,0))!=-1)
    {
	  connected++;
	  int errore;
	  sockets_s[ProcessingSock] = 1;
	  errore=fcntl(sockets[ProcessingSock],F_SETFL,O_NONBLOCK);

	  printf("Server: New client connected with id:%d\n", ProcessingSock);
	  printf("Server: Clients connected:%d\n", connected);
    }

	}
	else
	{
	//The client is not connected anymore
      if ((Quanti=read(sockets[ProcessingSock],buffer,sizeof(buffer)))==0)
      {
       printf("Client id:%d disconnected\n",ProcessingSock);
       CloseSocket(sockets[ProcessingSock]);
       sockets_s[ProcessingSock] = 0;
       connected--;
  	printf("Server: Clients connected:%d\n", connected);
      }
      if ( Quanti > 0 )
      {
	  
	        //Reset of the buffer by setting the last byte to 0
		buffer[Quanti]=0;		
		int ciclo = 0;
		printf ("\n\nServer: Received bytes: %dfrom client id: %d  (decimal format) \n", Quanti, ProcessingSock);
		for ( ciclo = 0; ciclo < Quanti; ciclo++)
		{
		printf (" %d ", (unsigned int)buffer[ciclo]);
		}
	        usleep(100);
		write(sockets[ProcessingSock], buffer, Quanti);
      }
	  

                               

      }
 

	}
	
  }
  
  //Server Close
  CloseSocket(DescrittoreSocket);
  printf("Server: Closed.\n");

  return 0;
}
