Thread: Sockets

  1. #1
    Registered User
    Join Date
    Feb 2013
    Posts
    100

    Sockets

    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;
        }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
      char* nodeNames[] = {"localhost", "localhost", "localhost"};
      int nodePorts[] = {1000, 2000, 3000};
    Where do you use this information?

    Your use of threads in the master is totally off, and completely unnecessary.

    Your master should be doing
    - connecting to the three servers using the nodeNames and nodePorts
    - send()'ing the start/end pair of numbers to each server
    - recv()'ing the answer back from each server
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sockets
    By deathkosui in forum C# Programming
    Replies: 1
    Last Post: 12-27-2009, 07:47 AM
  2. Sockets tutorial, datagram sockets example not working for me
    By caesius in forum Networking/Device Communication
    Replies: 14
    Last Post: 12-26-2009, 03:40 PM
  3. Sockets
    By devour89 in forum C++ Programming
    Replies: 10
    Last Post: 05-30-2003, 11:09 AM
  4. sockets
    By eldian() in forum C++ Programming
    Replies: 3
    Last Post: 04-28-2003, 07:08 AM
  5. help with sockets
    By fbplayr78 in forum C++ Programming
    Replies: 1
    Last Post: 04-13-2003, 08:55 PM