c - FIFO 读入 c 得到段错误

标签 c linux multithreading fifo

当我在无限循环中第二次使用 read 时出现段错误。我不明白为什么。

有代码。

#include <pthread.h>//serve per il multithreading
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>

#include <errno.h>//serve per gestione errori
#include <fcntl.h>//serve per le fifo
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
//VARIABILI GLOBALI
int lung_max_msg = 30;
int lung_min_chiave = 3;
int lung_max_chiave = 10;
char nome_server[30];

void* servi(char* nome_client, char* input_messaggio, char* input_chiave,
    char codec);

//void codificatore(char codec,char* msg,char* chiave,char* risultato);
int main()
{
  pthread_t pid;
  //pthread_t pid2,pid3;
  char* nome_client;
  int buf = 1000;
  char buffer[300];
  char* tmpcodec;
  char codec;
  char* input_messaggio;
  char* input_chiave;
  int numread;
  int fd;
  strcpy(nome_server, "miafifo");
  //strcpy(nome_client,"fifo_lettura");

  printf("Programma avviato......\n");
  printf("Attesa dei client......\n");

  //CREAO LA FIFO PER LEGGERE LE RICHIESTE DAI CLIENT
  int ret_val = mkfifo(nome_server, 0777);
  if ((ret_val == -1) && (errno != EEXIST))
  {
    perror("Errore durante la creazione della fifo!");
    exit(1);
  }
  printf("Ho creato la FIFO\n");
  //apro la fifo
  fd = open(nome_server, O_RDWR);
  printf("------Ho aperto la FIFO SERVER-------- \n");

  while (1) //continuo a cercare di leggere la fifo per vedere se ci sono altri client da servire
  {
    printf("sto per leggere...\n");
    numread = read(fd, &buffer, buf); // <----- PROBLEMA al secondo ciclo siccome esegue la servi().....

    if (numread < 0)
    {
      perror("Errore lettura buffer!\n");
      exit(1);
    }
    printf("\nIl buffer contiene :  \"%s\"\n", buffer);

    if (strcmp(buffer, "") != 0)
    {

      printf("nuovo client..\n");
      //prelevo nome_client,messaggio,chiave e codec
      nome_client = strtok(buffer, "$");
      input_messaggio = strtok(NULL, "$");
      input_chiave = strtok(NULL, "$");
      tmpcodec = strtok(NULL, "$");

      codec = tmpcodec[0];
      printf("Ho prelevato i dati...\n");
      printf("Nome client = %s \n", nome_client);
      printf("Ho letto tutti i dati\n");
      //creao un thread per gestire il client
      pthread_create(&pid, NULL,
          servi(nome_client, input_messaggio, input_chiave, codec), NULL );
      //printf("Ho finito l'esecuzione del thread....\n");
      //pthread_join(pid,NULL);
      //printf("Ho chiuso la fifo del server....\n");
      //strcpy(buffer,"");
      //close(fd);//chiudo la fifo del  server
      printf("Primo client servito..\n");

    }

    // memset(buffer,0,sizeof(buffer));
    strcpy(buffer, "");
  }          //fine while(1)

  printf("Sto chiudendo il server.....\n");

  //unlink(fd);
  exit(0);
}

void codificatore(char codec, char* msg, char* chiave, char* ris, int lung_msg,
    int lung_chiave)
{
  printf("Entro nella procedura codificatore()\n");
  printf(
      "\ncodec = %c ,msg = %s ,chiave = %s ,ris = %s ,lung_msg = %d ,lung_chiave = %d \n\n\n",
      codec, msg, chiave, ris, lung_msg, lung_chiave);

  int maiuscolo;
  int i, j;
  for (i = 0, j = 0; i < lung_msg; i++)
  {
    //controllo se nel risultato la letterA sara maiuscola o minuscola
    //printf("ciclo for i = %d \n",i);
    if (isupper(msg[i]))
    {
      maiuscolo = 1;
    }
    else
    {
      maiuscolo = 0;
    }
    //trasformo tutto in minuscolo per fare piu semplicemente le operazioni di calcolo e traslitterazione
    //printf("Trasformo tutto in minuscolo\n");
    msg[i] = tolower(msg[i]);
    chiave[i] = tolower(chiave[i]);
    //printf("Ho fatto una trasformazione...\n");
    if (msg[i] == ' ')
    {
      ris[i] = ' ';
      //printf("  ");
    }
    else
    {
      //printf("Stampo dei valoti per il testing...\n");
      //printf("%d,",msg[i] - 96);
      //printf("ho stampato un valore...\n");
      //printf("%d",chiave[j] - 96);  //<----- segmentation fault!!!!!!!!!!!
      //printf("Ho finito di stampare...\n");

      //printf("controllo chiave\n");
      if (chiave[j] != ' ')
      {
        //printf("entro nel ciclo...\n");
        if (codec == '1')
        {
          //printf("Inzio la codificazione di una lettera\n");
          //questa trasformazione deve funzionare anche su codifiche diverse
          ris[i] = (((msg[i] - 96) + (chiave[j] - 96)) % 26) + 96;
          //printf("Ho fatto la codifica di una lettere!\n");
        }
        else
        {

          ris[i] = (((msg[i] - 96) - (chiave[j] - 96)));                 //+ 96;
          if (ris[i] < 1)
          {
            ris[i] = 26 + ris[i];

          }
          printf(" : %d,", ris[i]);
          ris[i] += 96;
        }

      }
      else
      {
        ris[i] = ' ';
      }

      if (maiuscolo)
      {
        ris[i] = toupper(ris[i]);
      }

      j = (j + 1) % lung_chiave;
    }
    //printf("\n\n");
  }

  ris[lung_msg] = '\0';
  //stampa RISULTATO

}

void* servi(char* nome_client, char* input_messaggio, char* input_chiave,
    char codec)
{

  printf("Etro in servi()\n");
  char msg[31];
  char chiave[11];
  char ris[30];
  int m;
  char errore_input = '0';
  char msg_errore[300];

  //creao la fifo per mandare dati al client

  int fb = open(nome_client, O_WRONLY);
  printf("Ho aperto la FIFO per la scrittura.....\n");

  //CONTROLLO DATI IN INPUT
  int lung_chiave = strlen(input_chiave);
  int lung_msg = strlen(input_messaggio);
  char* tmperror[10];
  strcpy(msg_errore, "");
  if (lung_msg > lung_max_msg)
  {
    sprintf(tmperror, "%d", lung_max_msg);
    strcat(msg_errore, "\n\nLunghezza massima messaggio  = ");
    strcat(msg_errore, tmperror);
    errore_input = '1';
  }
  if (lung_chiave < lung_min_chiave)
  {
    sprintf(tmperror, "%d", lung_min_chiave);
    strcat(msg_errore, "\n\nLunghezza minima chiave = ");
    strcat(msg_errore, tmperror);
    errore_input = '1';
  }
  if (lung_chiave > lung_max_chiave)
  {
    sprintf(tmperror, "%d", lung_max_chiave);
    strcat(msg_errore, "\n\nLunghezza massima chiave = ");
    strcat(msg_errore, tmperror);
    errore_input = '1';
  }
  strcpy(msg, input_messaggio);
  strcpy(chiave, input_chiave);

  //funzione che codifica il messaggio
  //char ascii ->stampabili iniziano dal numero  32 al 126
  if (errore_input == '0')
  {
    printf("\nSto elaborando il msg!\n\n");
    sleep(1);

    //INVIO TUTTI I DATI ALLA FUNZIONE CHE CODIFICA DECODIFICA
    //void codificatore(char codec,char* msg,char* chiave,char* ris,int lung_msg,int lung_chiave)

    codificatore(codec, msg, chiave, ris, lung_msg, lung_chiave);

    printf("Risultato :  ");
    for (m = 0; m < lung_msg; m++)
    {
      printf("%c ", ris[m]);
    }
  }    //fine controllo errore input

  //ORA INVIO IL RISULTATO AL CLIENT   
  if (errore_input == '1')
  {
    printf("\nERRORE:%s\n", msg_errore);

    write(fb, "34$", 3);    //indico al client che c'è stato un errore
    write(fb, msg_errore, strlen(msg_errore));
    write(fb, "$", 1);

  }
  else    //invio il risultato al client
  {

    write(fb, "27$", 3); //indico al cient che il risultato è corretto e no ci sono errori
    write(fb, ris, strlen(ris));
    write(fb, "$", 1);

    printf("\nRisultato inviato al client\n");
  }

  //chiusura fifo

  //close(fb);
  printf(
      "\n-------------------------------------------------------------------------\n");

  sleep(1);
}

最佳答案

行内

numread = read(fd,&buffer,buf);

buffer 有 300 字节的空间,但 buf 要求将 1000 字节复制到它。

你要么需要增加buffer的容量

#define MAX_BYTES (1000)
int buf = MAX_BYTES;
char buffer[MAX_BYTES];

或者减小buf的值

#define MAX_BYTES (300)
int buf = MAX_BYTES;
char buffer[MAX_BYTES];

关于c - FIFO 读入 c 得到段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24096799/

相关文章:

检查值是否在音叉反汇编中

c - 重定向标准输入 - C

node.js - NodeJS API 服务失败如何重启?

java - 在Java中,当我在TextArea中使用多线程时,遇到问题

java - 使用线程发出数据库请求

有人可以帮我在这里找到段错误吗?

c - 在docker容器中获取主机IP

java - 这个Stack类有一些多线程问题吗?

C从XML中提取数据

linux - 构建 Gem native 扩展