#include#include#include#include#include#include#defineTRUE1#definePORT51500intmain(int argc,char*argv[]){int master_sock,
addrlen,
new_sock,
maximum_clients =30,
client_sock[maximum_clients],
act,
i,
value_read,
sock_descriptor,
maximum_socket_descriptor;structsockaddr_in adr{};char buff[1024];//data buffer of 1K
fd_set read_fds;//set of socket file descriptorschar*message ="ECHO Daemon v1.0 \r\n";//connect notice message//initialise all client_sock to 0for(i =0; i < maximum_clients; i++){
client_sock[i]=0;}//creating a master socketif((master_sock =socket(AF_INET, SOCK_STREAM,0))==0){perror("Failed_Socket");exit(EXIT_FAILURE);}//These are the types of sockets that we have created
adr.sin_family = AF_INET;//PROTOCOL = IP
adr.sin_addr.s_addr = INADDR_ANY;//SOURCE ADDRESS = 0.0.0.0/0
adr.sin_port =htons(PORT);//LISTENING PORT = PORT//bind the socket to localhost portif(bind(master_sock,(structsockaddr*)&adr,sizeof(adr))<0){perror("Failed_Bind");exit(EXIT_FAILURE);}printf("Port having listener: %d \n", PORT);//Specify 3 as maximum pending connections for master socketif(listen(master_sock,3)<0){perror("listen");exit(EXIT_FAILURE);}//Accepting the Incoming Connection
addrlen =sizeof(adr);puts("Looking For Connections");//*******************************//// Here we start using select functions and the macros for multiple client handlingwhile(TRUE){//Clearing the socket setFD_ZERO(&read_fds);//Adding the master socket to the setFD_SET(master_sock,&read_fds);
maximum_socket_descriptor = master_sock;//Adding child sockets to setfor(i =0; i < maximum_clients; i++){//Descriptor for Socket
sock_descriptor = client_sock[i];//if the socket descriptor is valid then adding it to the read listif(sock_descriptor >0){FD_SET(sock_descriptor,&read_fds);}//Highest File Descriptor Number which is needed for the select functionif(sock_descriptor > maximum_socket_descriptor){
maximum_socket_descriptor = sock_descriptor;}}//Waiting for something to happen on the master socket. As the wait time is NULL the wait is indefinite
act =select(maximum_socket_descriptor +1,&read_fds,nullptr,nullptr,nullptr);if((act <0)&&(errno != EINTR)){printf("Failed_Select");}//Any activity on the master socket is treated as an incoming connectionif(FD_ISSET(master_sock,&read_fds)){if((new_sock =accept(master_sock,(structsockaddr*)&adr,(socklen_t *)&addrlen))<0){perror("Accept!");exit(EXIT_FAILURE);}//Informing the user of the socket number which will be sued to send and receive messagesprintf("This is a New Connection,The socket file descriptor is %d and the IP is : %s on Port : %d\n",
new_sock,inet_ntoa(adr.sin_addr),ntohs(adr.sin_port));// Sending Greeting Message on New Connectionif(send(new_sock, message,strlen(message),0)!=strlen(message)){perror("Send!!");}puts("Welcome Text Sent Affirmative.");// Adding new socket to the array of socketsfor(i =0; i < maximum_clients; i++){// Checking if the position is emptyif(client_sock[i]==0){
client_sock[i]= new_sock;printf("Adding new socket to the list of sockets as %d\n", i);break;}}}//If not the master socket then it is some i/o activity on some other socketfor(i =0; i < maximum_clients; i++){
sock_descriptor = client_sock[i];if(FD_ISSET(sock_descriptor,&read_fds)){//Checking if the activity was for closing and reading the incoming messageif((value_read =read(sock_descriptor, buff,1024))==0){//If someone disconnected, getting their details and printing a messagegetpeername(sock_descriptor,(structsockaddr*)&adr,(socklen_t *)&addrlen);printf("Disconnected Host. Their , IP %s and PORT %d \n",inet_ntoa(adr.sin_addr),ntohs(adr.sin_port));//Closing the socket and marking it as 0 in the list to be reusedclose(sock_descriptor);
client_sock[i]=0;}else{//Setting the string terminating NULL byte on the end of the data that is read
buff[value_read]='\0';//Echoing back the message that came in the socketsend(sock_descriptor, buff,strlen(buff),0);}}}}return0;}