Member Avatar for andylbh

Hi guys, I'm trying to do a client server socket program, where the client writes a list of numbers for the server to compute, and then finally server returns a result.

I've managed to get my functions working the way I want (not in client/server)
But I've problem implementing it into client server.

Here's my code (not client/server yet)
It will read in a text file, and then calculate the Sum Of Prime numbers between the upper limit and lower limit.

prime.c

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define MAX_PATH_LENGTH 2048
#define MAX_FILENAME_LENGTH 256
#define MAX_LINE_LENGTH 256
#define MAX_RECORDS 50

const char NULL_CHAR = (char) 0;

struct rec
{
	char name[MAX_LINE_LENGTH];
	unsigned int lowerLimit;
	unsigned int upperLimit;
};

struct rec records[MAX_RECORDS];

int main()
{
	char buffer[MAX_PATH_LENGTH];
	char filename[MAX_FILENAME_LENGTH];
	char line[MAX_LINE_LENGTH];
	int len;
	FILE *pFile;
	char *pTok;
	const char *delim = ",";
	const char *delimLast = "\r\n";
	unsigned int firstNo, secondNo;
	int count, n;
	printf("Enter File Name: ");
	fgets(filename, MAX_FILENAME_LENGTH - 1, stdin);
	len = strlen (filename);
	if (filename [len - 1] == '\n')
	{
		filename [len - 1] = NULL_CHAR;
	}
	if ((pFile = fopen (filename, "r")) == NULL)
	{
		printf("Cannot Open File \n");
	}

	for (count = 0; count < MAX_RECORDS;)
	{
		if (fgets (line, MAX_LINE_LENGTH - 1, pFile) == NULL)
		{
			break;
		}

		pTok = strtok (line, delim);

		if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
		{
			continue;
		}
		
		records[count].lowerLimit = strtoul(pTok, NULL, 0);
		pTok = strtok(NULL, delimLast);
		records[count].upperLimit = strtoul(pTok, NULL, 0);

		count++;
	}

	double processingTime;
	double aveProcessingTime;
	double totalWaitingTime;
	double aveWaitingTime;
	time_t start, stop;
	double diff;
	double waitingTime[count];
	start = time(NULL);
	waitingTime[0] = 0;
	for (n = 0; n < count; n++)
	{	
		time_t start2, stop2;	
		printf("\n");
		printf("Process %d, ", n+1);
		printf("Waited for : %0.2fs\n", waitingTime[n]);
		printf("Lower Limit is %u, Upper Limit is %u\n", records[n].lowerLimit, records[n].upperLimit);
		//start2 = time(NULL);
		printf("Sum Of Primes: %u \n", sumOfPrimes(records[n].lowerLimit, records[n].upperLimit) );
		stop2 = time(NULL);
		totalWaitingTime = totalWaitingTime + waitingTime[n];
		waitingTime[n+1] = difftime(stop2,start);
	}
	stop = time(NULL);

	processingTime = difftime(stop,start);
	aveProcessingTime = processingTime/n;
	aveWaitingTime = totalWaitingTime/n;

	printf("\n");
	printf("Total no. of jobs : %d\n", n);
	printf("Total waiting time (secs) : %0.2f\n", totalWaitingTime);
	printf("Total processing time (secs) : %0.2f\n", processingTime);
	printf("Ave. waiting time (secs) : %0.2f\n",aveWaitingTime);
	printf("Ave. processing time (secs) : %0.2f\n", aveProcessingTime);
	printf("\n");
	
	return 0;
}

bool isPrime(unsigned int aNumber)
{
	unsigned int divisor = 2;
	
	while (divisor < aNumber)
	{
		if((aNumber % divisor)==0)
		{
			return false;
		}
		divisor++;
	}
	
	return true;
}

int sumOfPrimes(unsigned int lowerLimit,unsigned int upperLimit)
{
	unsigned int total = 0;
	unsigned int num = lowerLimit + 1;
	
	while (num < upperLimit)
	{
		if(isPrime(num)==true)
		{
			total = total + num;
		}
		num++;
	}
	
	return total;
}

this is the text file that is being read.

myfile.txt

1,10
500,1000
1000,5000
5000,10000

I tried implementing into server/client. I managed to get connected, but server isnt returning me any results.

client.c

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>            /* for sockaddr_un struct*/

#define MAX_PATH_LENGTH 2048
#define MAX_FILENAME_LENGTH 256
#define MAX_LINE_LENGTH 256
#define MAX_RECORDS 50
#define DEFAULT_PROTOCOL    0

/* POSIX renames "Unix domain" as "local IPC."
    Not all systems define AF_LOCAL and PF_LOCAL (yet). */
#ifndef AF_LOCAL
#define AF_LOCAL    AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL    PF_UNIX
#endif

/****************************************************************/

const char NULL_CHAR = (char) 0;

struct rec
{
	char name[MAX_LINE_LENGTH];
	unsigned int lowerLimit;
	unsigned int upperLimit;
};

struct rec records[MAX_RECORDS];

main  ()
{
	int clientFd, serverLen, result;
	struct sockaddr_un serverAddress;
	struct sockaddr* serverSockAddrPtr;

	serverSockAddrPtr = (struct sockaddr*) &serverAddress;
	serverLen = sizeof (serverAddress);

	/* Create a socket, bidirectional, default protocol */
	clientFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);
	serverAddress.sun_family = AF_LOCAL; /* Server domain */
	strcpy (serverAddress.sun_path, "prime"); /* Server name */

	do /* Loop until a connection is made with the server */	
	{
		result = connect(clientFd, serverSockAddrPtr, serverLen);
		if (result == -1)
		{
		sleep (1); /* Wait and then try again */
		}
	}
	while(result == -1);

	char buffer[MAX_PATH_LENGTH];
	char filename[MAX_FILENAME_LENGTH];
	char line[MAX_LINE_LENGTH];
	int len;
	int len2;
	int len3;
	FILE *pFile;
	char *pTok;
	const char *delim = ",";
	const char *delimLast = "\r\n";
	unsigned int firstNo, secondNo;
	int count, n;
	printf("Enter File Name: ");
	fgets(filename, MAX_FILENAME_LENGTH - 1, stdin);
	len = strlen (filename);
	if (filename [len - 1] == '\n')
	{
		filename [len - 1] = NULL_CHAR;
	}
	if ((pFile = fopen (filename, "r")) == NULL)
	{
		printf("Cannot Open File \n");
	}

	for (count = 0; count < MAX_RECORDS;)
	{
		if (fgets (line, MAX_LINE_LENGTH - 1, pFile) == NULL)
		{
			break;
		}

		pTok = strtok (line, delim);

		if (pTok == NULL || *pTok == NULL_CHAR || *pTok == '\n')
		{
			continue;
		}
	
		records[count].lowerLimit = strtoul(pTok,NULL,0);
		pTok = strtok(NULL, delimLast);
		records[count].upperLimit = strtoul(pTok,NULL,0);

		count++;
	}

	for (n = 0; n < count; n++)
	{	
		write(clientFd, records[n].lowerLimit);
		write(clientFd, records[n].upperLimit);
		readResults(clientFd);
	}
}

/**************************************************************/

readResults(fd)
int fd;
{
	char str[200];

  	while (readLine (fd, str)) /* Read lines until end-of-input */
 	printf ("%s\n", str); /* Echo line from socket */
}
/***************************************************************/

readLine (fd, str)
int fd;
char* str;

/* Read a single NULL-terminated line */
{
	int n;
	do /* Read characters until NULL or end-of-input */
	{
		n = read (fd,str, 1); /* Read one character */
	}
	while (n > 0 && *str++ != 0);

	return (n > 0); /* Return false if end-of-input */
}
/***************************************************************/

server.c

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>       /* for sockaddr_un struct */
#define DEFAULT_PROTOCOL   0

/* POSIX renames "Unix domain" as "local IPC."
    Not all systems define AF_LOCAL and PF_LOCAL (yet). */
#ifndef AF_LOCAL
#define AF_LOCAL    AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL    PF_UNIX
#endif

/****************************************************************/
main  ()
{
	int serverFd, clientFd, serverLen, clientLen;
	struct sockaddr_un serverAddress;/* Server address */
	struct sockaddr_un clientAddress; /* Client address */
	struct sockaddr* serverSockAddrPtr; /* Ptr to server address */
	struct sockaddr* clientSockAddrPtr; /* Ptr to client address */

	/* Ignore death-of-child signals to prevent zombies */
	signal (SIGCHLD, SIG_IGN);

	serverSockAddrPtr = (struct sockaddr*) &serverAddress;
	serverLen = sizeof(serverAddress);

	clientSockAddrPtr = (struct sockaddr*) &clientAddress;
	clientLen = sizeof(clientAddress);

	/* Create a socket, bidirectional, default protocol */
	serverFd = socket(AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);
	serverAddress.sun_family = AF_LOCAL; /* Set domain type */
	strcpy(serverAddress.sun_path, "prime"); /* Set name */
	unlink("prime"); /* Remove file if it already exists */
	bind(serverFd, serverSockAddrPtr, serverLen); /* Create file */
	listen(serverFd, 5); /* Maximum pending connection length */
	
	pid_t child_pid;
	unsigned int lowerLimit;
	unsigned int upperLimit;
	
	while (1) /* Loop forever */
	{
		/* Accept a client connection */
		clientFd = accept(serverFd, clientSockAddrPtr, &clientLen);

		child_pid = fork();

		if (child_pid < 0)
		{
			printf("Fork Failed");
		}
		
		if (child_pid == 0) /* Create child */
		{

			while(1)
			{
			close(serverFd);

			if (clientFd < 0)
			{
				error("ERROR on accept");
			}

			read(clientFd,lowerLimit);
			read(clientFd,upperLimit);
			write(clientFd,sumOfPrimes(lowerLimit,upperLimit));
			close(clientFd);
			}
		}

		else
		{
			close(clientFd); /* Close the socket */
		}

	}
}

/*********************************************************************/

bool isPrime(unsigned int aNumber)
{
	unsigned int divisor = 2;
	
	while (divisor < aNumber)
	{
		if((aNumber % divisor)==0)
		{
			return false;
		}
		divisor++;
	}
	
	return true;
}

int sumOfPrimes(unsigned int lowerLimit,unsigned int upperLimit)
{
	unsigned int total = 0;
	unsigned int num = lowerLimit + 1;
	
	while (num < upperLimit)
	{
		if(isPrime(num)==true)
		{
			total = total + num;
		}
		num++;
	}
	
	return total;
}

/*********************************************************************/

Please advise.
Thanks in advance.

I'm not sure what C compiler your using but you should use one that's modern..

these lines are wrong

read(clientFd,lowerLimit);
read(clientFd,upperLimit);
write(clientFd,sumOfPrimes(lowerLimit,upperLimit));

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

Please note the number of arguments.

Member Avatar for andylbh

hmm, I suppose I've the latest compiler for c?
Currently working this program in Ubuntu 9.04.
compile using:
cc server.c -o server
cc client.c -o client
and running using:
./server& (running in background)
./client

Thanks anyway, I tried having all 3 arguments in, but still didnt work.
I tried declaring a fixed unsigned int for lower and upper limit:

unsigned int lowerLimit = 1;
unsigned int upperLimit = 10;

write(clientFd,sumOfPrimes(lowerLimit,upperLimit),200);

It still didn't return the computation results over.
What is wrong?

try compiling with these switches

gcc filename.c -ansi -Wall -pedantic -o filename

This line

write(clientFd,sumOfPrimes(lowerLimit,upperLimit),200);

sumOfPrimes returns an int which you are saying is 200 bytes big...It should be

int ans = sumOfPrimes(lowerLimit,upperLimit);
write(clientFd, (const void*)&ans,sizeof(int));
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.