mas bro
mas bro

Reputation: 312

Program run not as I expected

I wonder why my program run but not as I expected. I'm making client-server using fork() but the result is : server2: success, but not listening as I want it. I compile it with gcc -o server2 server2.c

here is the server side :

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h> // trap the child exits and prevent zombies
#include <signal.h> // trap the child exits and prevent zombies
#include <stdlib.h>

// signal handler calls waitpid()
void sigchld_handler(int signo)
{
    while(waitpid(-1, NULL, WNOHANG) > 0);
}

// declares variabel
int main(int argc, char *argv[])
{
    struct sockaddr_in sAddr;
    int listensock;
    int newsock;
    char buffer[25];
    int result;
    int nread;
    int pid;
    int val;

// create socket that will accept connection
    listensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// set our SO_REUSEADDR option
    val = 1;
    result = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
    if(result < 0){
      perror("server1 multiplexing");
      return 0;
    }

// bind to local port and all addresses associated with the machine
    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(1972);
    sAddr.sin_addr.s_addr = INADDR_ANY;
    result = bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr));
    if(result < 0){
      perror("server2");
      return 0;
    }

// put the socket into listening mode for incoming connections
    result = listen(listensock, 5);
    if(result < 5){
      perror("server2");
      return 0;
    }

// before start looping, we install our signal handler
    signal(SIGCHLD, sigchld_handler);

// call accept() to block waiting for connection request from clients, after accept returns call fork() to create a new process
    while(1){
      newsock = accept(listensock, NULL, NULL);
      if((pid = fork()) == 0){

// close listening socket, read char from client vice versa, close the socket and exit child process
        printf("child process %i created.\n", getpid());
        close(listensock);

      nread = recv(newsock, buffer, 25, 0);
      buffer[nread] = '\0';
      printf("%s\n", buffer);
      send(newsock, buffer, nread, 0);
      close(newsock);
      printf("child process %i finished.\n", getpid());
      exit(0);
      }else{
      printf("child process error");    
      }

// parents process close
    close(newsock);
    }
}

and here is the client :

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>

void child_func(int childnum);

// main function
int main(int argc, char *argv[])
{
    int nchildren = 1;
    int pid;
    int x;

    if (argc > 1){
    nchildren = atoi(argv[1]);
    }

    for (x=0; x < nchildren; x++){
      if((pid = fork() == 0)){
        child_func(x+1);
        exit(0);
      } 
    }
    wait(NULL);
    return 0;
}
    void child_func(int childnum){
    int sock;
    struct sockaddr_in sAddr;
    char buffer[25];

    // create client socket and bind it to local pprt
    memset((void *) &sAddr, 0, sizeof(struct sockaddr_in));
    sAddr.sin_family = AF_INET;
    sAddr.sin_addr.s_addr = INADDR_ANY;
    sAddr.sin_port = 0;

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    bind(sock, (const struct sockaddr *) &sAddr, sizeof(sAddr));
    // Attempt to connect to whichever server is running on the local machine
    sAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    sAddr.sin_port = htons(1972);

    if (connect(sock, (const struct sockaddr *) &sAddr, sizeof(sAddr)) != 0){
    perror("client");   
    return;
    }
    // send some character to the server and insert sleep() function
    snprintf(buffer, 128, "data from client #%i.", childnum);
    sleep(1);
    printf("child #%i sent %zu chars\n", childnum, send(sock, buffer, strlen(buffer), 0));
    sleep(1);
    printf("child #%i received %zu chars\n", childnum, recv(sock, buffer, 25, 0));
    //close connection
    sleep(1);
    close(sock);

}

Upvotes: 1

Views: 70

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409196

I think I know why you get the output

server2: success

and then why it exits.

It because of how you check for errors from the listen function. On error it returns -1 and on success it returns 0. Just like most other system calls. It does not return number you passed to it on success.

So the listen call succeeds and returns 0, but then you check for result < 5 and zero is indeed less than five, so you print the "error" and exit the program.

Upvotes: 2

Related Questions