I'm using sockets in C to write 10 bytes to a socket and then read 10 bytes from that socket. I create a parent process that forks, creating a child that acts as the socket server that writes the 10 bytes. After the 10 bytes are wrote, back in the parent, those 10 bytes get read from the socket. This is what is supposed to happen. My current output just shows the server "waiting". I'm not sure what's causing the hangup between the parent/child but any help or suggestions would be much appreciated. Here's my code below.

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <time.h>
#include <sys/wait.h>

int main() {
  int counter=-1;
  int data_processed;
  int sockfd;
  int len;
  int result;
  int x;
  int i;
  int server_sockfd;
  int client_sockfd;
  int server_len;
  int fork_result;
  int stat_val;
  char buffer[BUFSIZ + 1];
  const char some_data[] = "Cat in Hat";
  const char null_msg[] = "\0";
  pid_t pid_parent;
  pid_t pid_child;
  pid_parent=getpid();
  srand( time(NULL) );
  x = rand() % 7 + 3;
  unsigned int client_len;
  struct sockaddr_un server_address;
  struct sockaddr_un client_address;
  struct sockaddr_un address;

  fork_result = fork();
  if (fork_result == 0) {
    pid_child=getpid();
    unlink("server_socket");
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "server_socket");
    server_len = sizeof(server_address);
    bind(server_sockfd, (struct sockaddr*)&server_address, server_len);

    listen(server_sockfd, 5);
    printf("server waiting\n");
    client_len = sizeof(client_address);
    client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len); 
    for(i = 0; i < x; i++) {
      data_processed = write(client_sockfd, some_data,strlen(some_data));
      printf("%d - Wrote %d bytes\n",pid_child, data_processed); 
    }
    data_processed = write(client_sockfd, null_msg, 1);      
    return (x);
  }	
 
  pid_child=wait(&stat_val);
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  address.sun_family = AF_UNIX;
  strcpy(address.sun_path, "server_socket");
  len = sizeof(address);

  result = connect(sockfd, (struct sockaddr*)&address, len);
	
  while(1) {
    counter++;
    memset(buffer, '\0', sizeof(buffer));
    data_processed = read(sockfd, buffer, 10);
    if(buffer[0] == 0) {
      break;
    }
    printf("%d - Read %d bytes: %s\n", pid_parent, data_processed, buffer);  
  }
  close(sockfd);
  
  
  exit (0);
}

Recommended Answers

All 8 Replies

Try making the following edits to your code:

fprintf (stderr, "[Child] Tring to accept...\n");
    client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len);
    fprintf (stderr, "[Child] done!\n");

and

fprintf (stderr, "[Parent] waiting for child...\n");
  pid_child=wait(&stat_val);
  fprintf (stderr, "[Parent] done waiting\n");

In the parent, you are waiting for the child to exit while the child is waiting for the connect from the parent to do its work.

Hey, thanks for the reply! I made edits to my code as you suggested and my output changed to this:

[Parent] waiting for child...
server waiting
[Child] Tring to accept...

I think the issue here is that the child is failing to accept. Perhaps I have an error in my accept call. Any ideas?

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <time.h>
#include <sys/wait.h>

int main() {
  int counter=-1;
  int data_processed;
  int sockfd;
  int len;
  int result;
  int x;
  int i;
  int server_sockfd;
  int client_sockfd;
  int server_len;
  int fork_result;
  int stat_val;
  char buffer[BUFSIZ + 1];
  const char some_data[] = "Cat in Hat";
  const char null_msg[] = "\0";
  pid_t pid_parent;
  pid_t pid_child;
  pid_parent=getpid();
  srand( time(NULL) );
  x = rand() % 7 + 3;
  unsigned int client_len;
  struct sockaddr_un server_address;
  struct sockaddr_un client_address;
  struct sockaddr_un address;

  fork_result = fork();
  if (fork_result == 0) {
    pid_child=getpid();
    unlink("server_socket");
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "server_socket");
    server_len = sizeof(server_address);
    bind(server_sockfd, (struct sockaddr*)&server_address, server_len);

    listen(server_sockfd, 5);
    printf("server waiting\n");
    client_len = sizeof(client_address);
    fprintf (stderr, "[Child] Tring to accept...\n");
    client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_address, &client_len);
    fprintf (stderr, "[Child] done!\n");
    for(i = 0; i < x; i++) {
      data_processed = write(client_sockfd, some_data,strlen(some_data));
      printf("%d - Wrote %d bytes\n",pid_child, data_processed); 
    }
    data_processed = write(client_sockfd, null_msg, 1);      
    return (x);
  }	
 
  fprintf (stderr, "[Parent] waiting for child...\n");
  pid_child=wait(&stat_val);
  fprintf (stderr, "[Parent] done waiting\n");
  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  address.sun_family = AF_UNIX;
  strcpy(address.sun_path, "server_socket");
  len = sizeof(address);

  result = connect(sockfd, (struct sockaddr*)&address, len);
	
  while(1) {
    counter++;
    memset(buffer, '\0', sizeof(buffer));
    data_processed = read(sockfd, buffer, 10);
    if(buffer[0] == 0) {
      break;
    }
    printf("%d - Read %d bytes: %s\n", pid_parent, data_processed, buffer);  
  }
  close(sockfd);
  
  
  exit (0);
}

I am not sure about this but where did you assign a value to server_address?

I'm pretty sure I'm assigning a value to it in the code here:

server_address.sun_family = AF_UNIX;
strcpy(server_address.sun_path, "server_socket");
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr*)&server_address, server_len);

Sorry, I am not good with network stuff

I think the issue here is that the child is failing to accept. Perhaps I have an error in my accept call. Any ideas?

I described the problem. The parent is blocking waiting for the client to exit. The client is blocking waiting for the server to connect. You are in deadlock.

Remove the wait call since the client will never exit without the parent connecting to it. Use some type of IPC to coordinate between the parent and the child so that the parent runs after the child is in the accept state.

Ah ok! Thank you!

Ended up using sleep(5); in the place of the wait call. Works great!

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.