Sindbad~EG File Manager

Current Path : /home/beeson/public_html/WebMathXpert/Demos/
Upload File :
Current File : //home/beeson/public_html/WebMathXpert/Demos/ServerExample.c

//Example code: A simple server side code, which echos back the received message. 
//Handle multiple socket connections with select and fd_set on Linux 
#include <stdio.h> 
#include <string.h> //strlen 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> //close 
#include <arpa/inet.h> //close 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <sys/time.h> //FD_SET, FD_ISSET, FD_ZERO macros 
	
#define TRUE 1 
#define FALSE 0 
#define PORT 123459 
#define INBUFFER_SIZE (1 << 10)
#define OUTBUFFER_SIZE (1 << 12)  // about 800kb
#define MAXCLIENTS 10

	
int main(int argc , char *argv[]) 
{ 
	int opt = TRUE; 
	int master_socket , addrlen , newsockfd , client_socket[MAXCLIENTS] , 
		mactivity, i , valread , sd; 
	int max_sd; 
	struct sockaddr_in address; 
		
	char buffer[OUTBUFFERSIZE]; //data buffer of 1K 
		
	//set of socket descriptors 
	fd_set readfds; 
		
	//a message 
	char *message = "ECHO Daemon v1.0 \r\n"; 
	
	//initialise all client_socket[] to 0 so not checked 
	for (i = 0; i < MAXCLIENTS; i++) 
	{ 
		client_socket[i] = 0; 
	} 
		
	//create a master socket 
	if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0) 
	{ 
		perror("socket failed"); 
		exit(EXIT_FAILURE); 
	} 
	
	//set master socket to allow multiple connections , 
	//this is just a good habit, it will work without this 
	if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, 
		sizeof(opt)) < 0 ) 
	{ 
		perror("setsockopt"); 
		exit(EXIT_FAILURE); 
	} 
	
	//type of socket created 
	address.sin_family = AF_INET; 
	address.sin_addr.s_addr = INADDR_ANY; 
	address.sin_port = htons( PORT ); 
		
	//bind the socket to localhost port given by PORT
	if (bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0) 
	{ 
		perror("bind failed"); 
		exit(EXIT_FAILURE); 
	} 
	printf("Listener on port %d \n", PORT); 
		
	if (listen(master_socket, MAXCLIENTS) < 0) 
	{ 
		perror("listen"); 
		exit(EXIT_FAILURE); 
	} 
	printf("Listening on port %d...\n", PORT);
	puts("Waiting for connections ..."); 
	
	addrlen = sizeof(address); 
	
		
	while(TRUE) 
	{ 
		//clear the socket set 
		FD_ZERO(&readfds); 
	
		//add master socket to set 
		FD_SET(master_socket, &readfds); 
		max_sd = master_socket; 
			
		//add child sockets to set 
		for ( i = 0 ; i < max_clients ; i++) 
		{ 
			//socket descriptor 
			sd = client_socket[i]; 
				
			//if valid socket descriptor then add to read list 
			if(sd > 0) 
				FD_SET( sd , &readfds); 
				
			//highest file descriptor number, need it for the select function 
			if(sd > max_sd) 
				max_sd = sd; 
		} 
	
		//wait for an activity on one of the sockets , timeout is NULL , 
		//so wait indefinitely 
		activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL); 
	
		if ((activity < 0) && (errno!=EINTR)) 
		{ 
			printf("select error"); 
		} 
			
		//If something happened on the master socket , 
		//then its an incoming connection 
		if (FD_ISSET(master_socket, &readfds)) 
		{ 
			if ((newsockfd = accept(master_socket, 
					(struct sockaddr *)&address, (socklen_t*)&addrlen))<0) 
			{ 
				perror("accept"); 
				continue;   
			} 
			
			//write on server console information about the  socket number - used in send and receive commands
			printf("New connection , socket fd is %d , ip is : %s , port : %d\n" ,
			       newsockfd , inet_ntoa(address.sin_addr) , ntohs (address.sin_port)
					); 
			
			//add new socket to array of sockets 
			for (i = 0; i < max_clients; i++) 
			{ 
				//if position is empty 
				if( client_socket[i] == 0 ) 
				{ 
					client_socket[i] = newsockfd; 
					printf("Adding to list of sockets as %d\n" , i); 
					break; 
				} 
			} 
			if(i==max_clients)
				{ 
					printf("No more clients allowed\n");
					close(newsockfd);
					continue;
				}
	  // Receive data from client
	         ssize_t dataSize = recv(newsockfd, buffer, sizeof(buffer), 0);
	         if (dataSize <= 0)
	           {
	             perror("Socket receive error");
	             close(newsockfd);
	             continue; // Continue to the next iteration
	           }

	          // process data
        
	         buffer[dataSize] = '\0';
	         printf("Received data: %s\n", buffer);
	         char *sessionId = strtok(buffer, "|");  // Get the session ID
	         char *message = strtok(NULL, "|");
	         char *param = strtok(NULL, "|");       // which might be NULL
        
	         if (sessionId == NULL || message == NULL)
	         {
	             perror("Invalid message format");
	             close(newsockfd);
	             continue; // Continue to the next iteration
	         }
        
	         //  Is this a new sessionId or not?
	         PDOCDATA storedDoc = (PDOCDATA) sizeof(DOCDATA);
	         HASH_FIND_STR(AllDocuments, sessionId, storedDoc);  // the first sessionId is the local variable
        
	         if (storedDoc == NULL)
	             { // new sessionID
	               createDocument(sessionId);
	               printf("Created document for %s\n", sessionId);
	               HASH_FIND_STR(AllDocuments, sessionId, storedDoc);
	               printf("message is %s\n", message);
	               printf("param is %s\n",param);
	             }
	         else
	             {
	               printf("Found existing document for %s\n", sessionId);
	             }
	         activate(storedDoc);
	         printf("Activating document\n");
	         int err = process_message(storedDoc, message, param, outbuffer);
	         int messagelength = (int) strlen(outbuffer);
	         printf("About to send %lu bytes\n", messagelength);
	         if(!err)
	            {
	               if( send(newsockfd,outbuffer, messagelength,0) < messagelength)
	                  { perror("Socket send error");
	                    // send can return -1; hence messagelength is (signed) int
	                    // send returns ssizet but if I use that type, it's not defined.
	                  }
	               else
	                  { printf("Sent a result back to the caller\n");
	                  }
	            }
	         else
	            {
	               printf("Not processed: %s", outbuffer);
	            }
			
		} 
			
		//else its some IO operation on some other socket 
		for (i = 0; i < max_clients; i++) 
		{ 
			sd = client_socket[i]; 
				
			if (FD_ISSET( sd , &readfds)) 
			{ 
				//Check if it was for closing , and also read the 
				//incoming message 
				if ((valread = read( sd , buffer, 1024)) == 0) 
				{ 
					//Somebody disconnected , get his details and print 
					getpeername(sd , (struct sockaddr*)&address , (socklen_t*)&addrlen); 
					printf("Host disconnected , ip %s , port %d \n" , 
					inet_ntoa(address.sin_addr) , ntohs(address.sin_port)); 
						
					//Close the socket and mark as 0 in list for reuse 
					close( sd ); 
					client_socket[i] = 0; 
				} 
					
				//Echo back the message that came in 
				else
				{ 
					//set the string terminating NULL byte on the end 
					//of the data read 
					buffer[valread] = '\0'; 
					send(sd , buffer , strlen(buffer) , 0 ); 
				} 
			} 
		} 
	} 
		
	return 0; 
} 

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists