1

I am trying to print the frame of the server in the client side, but i get segmentation fault or random symbols of the received frame, im guessing im not casting it correctly.

This is my frame:

typedef struct{
    char *information[100];
    uint8_t infoSize;
}resFrame;


typedef struct
{
    uint8_t option;
}reqFrame;

My server:

/*Array of thread for each client*/
pthread_t threads[BACKLOG];
pthread_mutex_t lock;

/*Declaring the function prototype*/
void *handle_client(void *socket_desc);



int main(int argc, char **argv) {
   int sockfd, newfd;
   struct sockaddr_in host_addr, client_addr;
   socklen_t sin_size;

   /*The used port is recived in the execution*/
   if(argc != 2) {
      perror("Usage: server <port>");
      exit(1);
   }

   if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
      perror("Socket failed");
      exit(1);
   }

   host_addr.sin_family = AF_INET;
   host_addr.sin_port = htons(atoi(argv[1]));
   host_addr.sin_addr.s_addr = INADDR_ANY;
   memset(&(host_addr.sin_zero), '\0', 8);

   if(bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1) {
      perror("Bind failed");
      exit(1);
   }

   if(listen(sockfd, BACKLOG) == -1) {
      perror("Listen failed");
      exit(1);
   }

   printf("Server ready, listening...\n");

   while(1) {
      sin_size = sizeof(struct sockaddr_in);
      if((newfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size)) == -1) {
         perror("Accept failed");
         continue;
      }

      printf("Connection from %s received\n", inet_ntoa(client_addr.sin_addr));

      /*A thread is created with the ID connection*/
      if(pthread_create(&threads[newfd], NULL, handle_client, &newfd) < 0) {
         perror("Thread creation failed");
         continue;
      }
   }

   if(close(sockfd) < 0) {
      perror("Close socket failed\n");
      exit(1);
   }

   return 0;
}


void *handle_client(void *socket_desc) {
    int sock = *(int*)socket_desc;
    int read_size;

    /*Frame structs*/
    reqFrame clientFrame;
    resFrame serverFrame;
   /*base de datos*/
     MYSQL *con = mysql_init(NULL);

  if (con == NULL)
  {
      fprintf(stderr, "mysql_init() failed\n");
      exit(1);
  }

  if (mysql_real_connect(con, "localhost", "cesar", "cesar",
          "wpsite", 0, NULL, 0) == NULL)
  {
      //finish_with_error(con);
  }

  if (mysql_query(con, "select meta_value from wp_frm_item_metas"))
  {
    //  finish_with_error(con);
  }

  MYSQL_RES *result = mysql_store_result(con);

  if (result == NULL)
  {
   //   finish_with_error(con);
  }

  int num_fields = mysql_num_fields(result);
  MYSQL_ROW row;
  char *bdData[num_fields];

  while ((row = mysql_fetch_row(result)))
  {
      for(int i = 0; i < num_fields; i++)
      {
       //   printf("%s ", row[i] ? row[i] : "NULL");
          bdData[i] = row[i];
       //   printf("%s",bdData[i]);
      }

      printf("\n");

      for(int j=0;j<num_fields;j++){
        serverFrame.information[j] = row[j];
     //    printf("%s\n",(char *)serverFrame.info[j]);
      }
      serverFrame.infoSize = num_fields;
  }

  mysql_free_result(result);
  mysql_close(con);

  /*final base de datos*/
   /*Always receiving messages form the clients on each thread*/
    while((read_size = recv(sock ,(char *)&clientFrame , sizeof(reqFrame) , 0)) > 0) 
    {

        if(send(sock, &serverFrame, sizeof(resFrame), 0) < 0) {
            perror("Send failed\n");
        }
     //   printf("size: %lu",sizeof(resFrame));
    }

      if(read_size == 0) {
         perror("Client disconnected\n");

      } else if(read_size == -1) {
         perror("Receive failed\n");
      }

      pthread_mutex_unlock(&lock);

   if(close(sock) < 0) {
      perror("Close socket failed\n");
   }

   pthread_exit(NULL);
}

My client:

pthread_mutex_t lock;


int main(int argc, char *argv[])
{
   int fd, numbytes;

   struct sockaddr_in server;

   /*Frame structs*/
   reqFrame clietnFrame;
   resFrame serverFrame;

   if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
      printf("socket() error\n");
      exit(-1);
   }

   server.sin_family = AF_INET;
   server.sin_port = htons(PORT);
   server.sin_addr.s_addr = inet_addr("192.168.1.11");
   bzero(&(server.sin_zero),8);

   if(connect(fd, (struct sockaddr *)&server,  sizeof(struct sockaddr))==-1){
      printf("connect() error\n");
      exit(-1);
   }
   printf("Connection Established\n");
   int option = 0;
   while(1){
         printf("For each selection, type the number that corresponds with your petition\n");
         printf("Available sensors:\n 1.-Accelerometer");

        scanf("%d",&option);
         pthread_mutex_lock(&lock);

         /*Sending the request frame*/
          send(fd,(char *)&clietnFrame,sizeof(reqFrame),0);

      /*Receiving the response frame*/
      if ((numbytes = recv(fd,(char *)&serverFrame,sizeof(resFrame),0)) == -1){
         perror("Error en recv() \n");
         continue;
      }

      system("clear");
      printf("The received frame is:\n");

      if(option == 1){
          for(int j=0;j<serverFrame.infoSize;j++){
       
 *             printf("%s\n",&serverFrame.information[j]);*//HERE IS MY ERROR
          }
      }
      else if(option ==2){
         for(int k=0;k<10;k++){
      
         }
      }
      
      pthread_mutex_unlock(&lock);
   
   }
   //printf("%s",serverFrame.name[0]);
   return 0;
}

I tried casting the result in different ways and convert the data in hexadecimal and send it to the client, but it seems that the data is missing.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
cesar
  • 23
  • 3
  • The fields are not null-terminated. You need to fetch the lengths of each field and use the lengths as variable precision fields in the `printf` calls and also check for `row[i]` values that are `NULL`. See the example in the [documentation](https://dev.mysql.com/doc/c-api/8.0/en/mysql-fetch-row.html). – Ian Abbott Apr 06 '23 at 17:30
  • There is no point sending the `serverFrame` variable contents as-is to the client because the only thing that will be sent is a bunch of pointer values, not the actual data. You will need to "serialize" the data sent over the socket. (Also, the pointers in `serverFrame.information[]` will be pointing to invalid data after the result has been freed by `mysql_free_result(result);`.) – Ian Abbott Apr 06 '23 at 17:43
  • ..and it's all broken anyway because you do not completely handle 'numbytes'. If the recv() call loads only one byte into the ServerFrame, (numbytes returned as 1), what happens to the following code, (UB)? – Martin James Apr 07 '23 at 06:59

0 Answers0