1

I have to create a client and server, where the client will send a character and an integer (using structs) and then my client will iterate the letter by n (integer) times and will send it back to the client.

For instance: a and 4 are sent from the client, server will manipulate and send a string of 4 a's (aaaa) back to the client.

I know I am really close to get the code but once I send my char and int, I get a "segmentation fault (core dumped) error". I have done my research and the error shows up due to a missing cast, memory being accessed where is not supposed to access, or that a pointer might be null.

The code is as follow:

Client:

// ClientTest.c
// opens fifo1 for writing and fifo2 for reading


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>


struct problem {        
    char letter[1];
    int number[1];
};
main (void)
{
  struct problem x=0; //Initializing structure to null
  int fda;  // to write to character server
  int fdb;  // to read response from character server
  int i;    // for the iteration


  printf("Client: Please enter a character: ");
  scanf("%c", &x.letter[0]); 
  printf("Client: Please enter an integer: ");
  scanf("%d", &x.number[0]);  

  memset(&x.letter, 0, 1);
  memset(&x.number, 0, 1);  


  if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
     printf("cant open fifo to write");

  if((fdb=open("FIFO2", O_RDONLY))<0)
     printf("cant open fifo to read");

  write(fda, x.number, 1);
  printf("\nClient: Got the integer sent, now waiting for response ");
  //sleep(0.250);
  write(fda, x.letter, 1);
  printf("\nClient: Got the character sent, now waiting for response ");

  char outletter[7];

  read(fdb, outletter, 7);
  printf("\nClient: received characters from server %c", outletter);

  close(fda);
  close(fdb);


  printf ("\nall done!\n");

}

server

// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

struct problem {
    char letter[1]; // struct to store the character
    int number [1]; // struct to store the integer
    };

main (void)
{
  struct problem x;
  int fda;  // to read from client char
  int fdb;  // to write to client char
  int finish;   // lets me know that client is done
  int i;    // because C needs this defined as int
  int p;
  char outletter[7];

  memset(&x.letter, 0, 7);
  memset(&x.number, 0, 1);


  /* Create the fifos and open them  */
  if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO1");
    exit(-1);
    }
  if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO2");
    exit(-1);
    }
  if((fda=open("FIFO1", O_RDONLY))<0)
     printf("cant open fifo to write");
  if((fdb=open("FIFO2", O_WRONLY))<0)
     printf("cant open fifo to read");

  read(fda, x.letter, 1); //read the character
  read(fda, x.number, 1);   //read the integer


  printf("\nServer: just got character: , %c", x.letter[0]);
  printf("\nServer: just got integer: , %d", x.number[0]);

  p=x.number[0]-'0';


  for( i = 0; i<=p; i++)                // iteration to create the character's string
    outletter[p] = x.letter[0];


  printf("iteration: %d and character: %c\n", i, outletter[0]); // validating the character and integer received
  printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client

  write(fdb, outletter, p); 
  printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client



  if(finish == 1)
    printf("\nServer: This says I am ready to close ");
  close(fda);
  close(fdb);
  unlink("FIFO1");
  unlink("FIFO2");
}
7
  • 2
    Your memset calls are all wrong. They're destroying the array address. And the length is wrong (first memset in your main). In the client you scanf then you memset (wrongly) to zero... Commented Sep 18, 2016 at 19:23
  • Given letter and number are both arrays of size 1, I'm struggling to see why they're arrays at all. Commented Sep 18, 2016 at 19:26
  • I knew it had to do something with the memsets, I have tried setting them to 1's, I also tried using size of x.letter and x.number, I will try to set them to something else then, hopefully it will work this time, other than that I believe (and hope) everything else should be pretty good for the most part, I hope I'm not wrong, I've been pulling my hair all week long Commented Sep 18, 2016 at 19:27
  • yes I agree the compiler is pretty weak, in fact I have to use a server compiler using putty (which I really hate because I have lost a lot of time by trial & error Commented Sep 18, 2016 at 19:29
  • 1
    You don't have to use a weak compiler all the time. Compile first on a well-enabled compiler and then compile using your target compiler. After all, code should be portable too. Good luck. Commented Sep 18, 2016 at 19:30

1 Answer 1

1

There are many problems with your code, I've made it running but you can still improve it.

Client:

// ClientTest.c
// opens fifo1 for writing and fifo2 for reading


#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>


struct problem {        
    char letter[1];
    int number[1];
};
main (void)
{
  struct problem x; 
  int fda;  // to write to character server
  int fdb;  // to read response from character server
  int i;    // for the iteration

  memset(&x, 0, sizeof(struct problem)) ;


  printf("Client: Please enter a character: ");
  scanf("%c", x.letter); 
  printf("Client: Please enter an integer: ");
  scanf("%d", x.number);  

// removed or else the letter and number would be reverted to zero
 // memset(&x.letter, 0, sizeof(char));
//  memset(&x.number, 0, sizeof(int));  


  if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
     printf("cant open fifo to write");

  if((fdb=open("FIFO2", O_RDONLY))<0)
     printf("cant open fifo to read");

  write(fda, x.letter, sizeof(char));
  printf("\nClient: Got the character sent, now waiting for response ");

  write(fda, x.number, sizeof(int));
  printf("\nClient: Got the integer sent, now waiting for response ");
  //sleep(0.250);

  char outletter[7];

  read(fdb, outletter, 7);
  printf("\nClient: received characters from server:") ;
  printf("%s\n", outletter);

  close(fda);
  close(fdb);


  printf ("\nall done!\n");

}

Server:

// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

struct problem {
    char letter[1]; // struct to store the character
    int number[1]; // struct to store the integer
    };

main (void)
{
  struct problem x;
  int fda;  // to read from client char
  int fdb;  // to write to client char
  int finish;   // lets me know that client is done
  int i;    // because C needs this defined as int
  int p;
  char outletter[7];

  memset(x.letter, 0, sizeof(char));
  memset(x.number, 0, sizeof(int));


  /* Create the fifos and open them  */
  if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO1");
    exit(-1);
    }
  if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
    {
    perror("cant create FIFO2");
    exit(-1);
    }
  if((fda=open("FIFO1", O_RDONLY))<0)
     printf("cant open fifo to write");
  if((fdb=open("FIFO2", O_WRONLY))<0)
     printf("cant open fifo to read");

  read(fda, x.letter, sizeof(char)); //read the character
  read(fda, x.number, sizeof(int));   //read the integer


  printf("\nServer: just got character: , %c", x.letter[0]);
  printf("\nServer: just got integer: , %d", x.number[0]);

  p=x.number[0];



  if (p > 6) p = 6;  // Cannot write more than 6 characters in outletter



  for( i = 0; i<=p; i++) {               // iteration to create the character's string
    outletter[i] = x.letter[0];
    printf("iteration: %d and character: %c\n", i, outletter[i]); // validating the character and integer received
  }
  outletter[p] = '\0'; // the string must finish with '\0'


  printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client

  write(fdb, outletter, p); 
  printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client



  if(finish == 1)
    printf("\nServer: This says I am ready to close ");
  close(fda);
  close(fdb);
  unlink("FIFO1");
  unlink("FIFO2");
}
Sign up to request clarification or add additional context in comments.

4 Comments

thanks for the suggestions, I see what were the minor changes you made, and now I'll try to improve it a little bit more. thanks for your help.
Be carefull of sizeof() because the size of an int is not 1.
one minor question, since i see that cannot write more than 6 letters in the outletter, I could always change the size of that particular array (since I made it 7) to something else like for instance, sizeof(number) or size it to MAX to not have a limit on the array right?
You need the 7th char for '\0' because it is the string terminator. You can make outletter dynamic with: char *outletter; outletter = malloc(p+1); then don't forget to free it when you're done with free(outletter);.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.