I'm trying to complete a basic socket program. I have a class which is the server and I have 3 clients/nodes. The master is supposed to split a range of values into three equal parts and pass each range of values to the nodes and find all the prime values in that range and return to the master and count them all. I got this working for a single node, but now I'm trying to get it working with three nodes, which I'm going to need threads for. I think I'm going to use pthreads for this. But the problem I'm snagged on at the moment is having the socket information in the function that is called when the threads actually call the sendRange() function. Not sure how I can send and receive in this fashion. I could maybe put all the socket code in the function maybe? Any ideas or possible fixes would be greatly appreciated!
Master:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
void* sendRange();
int main() {
int starting, ending;
printf("Enter starting & ending values: \n");
scanf("%d %d",&starting, &ending);
char* nodeNames[] = {"localhost", "localhost", "localhost"};
int nodePorts[] = {1000, 2000, 3000};
int nthreads = 3;
pthread_t ids[nthreads];
// Socket pointer
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
fprintf(stderr,"ERROR opening socket\n");
exit(0);
}
// port number
int portno = 7000;
// server address structure
struct sockaddr_in serv_addr;
// Set all the values in the server address to 0
memset(&serv_addr, '0', sizeof(serv_addr));
// Setup the type of socket (internet vs filesystem)
serv_addr.sin_family = AF_INET;
// Setup the port number
// htons - is host to network byte order
// network byte order is most sig bype first
// which might be host or might not be
serv_addr.sin_port = htons(portno);
// Setup the server host address
struct hostent *server;
server = gethostbyname("localhost");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); /// dest, src, size
// Connect to the server
if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
printf("ERROR connecting\n");
exit(0);
}
int n = ending-starting;
int t;
for(t = 0; t < nthreads; t++){
int* p = (int*)malloc(n*sizeof(int));
p[0] = t;
p[1] = (int)(t * ((double)n / (double)nthreads));// start
p[2] = (int)((t+1) * ((double)n / (double)nthreads));// stop
pthread_create(&(ids[t]), NULL, sendRange, (void*)p);
}
for(int i = 0; i < nthreads; i++){
pthread_join(ids[i], NULL);
}
printf("starting: %d", starting);
printf("\nending: %d\n", ending);
int primeCount = 0;
n = read(sockfd,&primeCount,sizeof(int));
if (n < 0) {
printf("ERROR reading from socket\n");
exit(0);
}
printf("%d\n",primeCount);
close(sockfd);
return 0;
}
void* sendRange(void* parm) {
int* pa = (int*) parm;
int starting = pa[1];
int ending = pa[2];
int n = write(sockfd,&starting,sizeof(int));
if (n < 0) {
printf("ERROR writing to socket\n");
exit(0);
}
n = write(sockfd,&ending,sizeof(int));
if (n < 0) {
printf("ERROR writing to socket\n");
exit(0);
}
}
Node:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int isPrime(int num);
int main() {
// Get a socket of the right type
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("ERROR opening socket");
exit(1);
}
// port number
int portno;
printf("portno: ");
scanf("%d", &portno);
// server address structure
struct sockaddr_in serv_addr;
// Set all the values in the server address to 0
memset(&serv_addr, '0', sizeof(serv_addr));
// Setup the type of socket (internet vs filesystem)
serv_addr.sin_family = AF_INET;
// Basically the machine we are on...
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// Setup the port number
// htons - is host to network byte order
// network byte order is most sig bype first
// which might be host or might not be
serv_addr.sin_port = htons(portno);
// Bind the socket to the given port
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
printf("ERROR on binding\n");
exit(1);
}
// set it up to listen
listen(sockfd,5);
int newsockfd;
struct sockaddr_in cli_addr;
socklen_t clilen = sizeof(cli_addr);
// Wait for a call
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
printf("ERROR on accept");
exit(1);
}
int starting;
int ending;
int n = read(newsockfd,&starting,(sizeof(int)));
if (n < 0) {
printf("ERROR reading from socket\n");
exit(1);
}
n = read(newsockfd,&ending,(sizeof(int)));
if (n < 0) {
printf("ERROR reading from socket\n");
exit(1);
}
int primeCount = 0;
for(int i = starting; i < ending; i++){
if(isPrime(i)){
primeCount++;
}
}
n = write(newsockfd,&primeCount,sizeof(int));
if (n < 0) {
printf("ERROR writing to socket\n");
exit(1);
}
close(newsockfd);
close(sockfd);
return 0;
}
int isPrime(int num){
for (int i = 2; i < num; i++){
if (num % i == 0 && i != num) return 0;
}
return 1;
}