client get segmentation fault when attach to share

2019-09-06 09:02发布

问题:

Hi i want to implement a client-server program that communicates with each other via shared memory. in the server side i have two threads. a writer thread and a reader thread. the writer thread puts some data into the queue and the reader thread reads from it and passes the data to the client side via shared memory.each client that has shmid can attach itself to it and read data from it...

right now i get segmentation fault at client side when it comes to attach to shared memory.

here is my code:

server side:

typedef struct shared_mem {
    char imgDir[100];
    int client_id;
    int read_client;
    sem_t shm_sem;
}shared_mem;
shared_mem *shared;

int main(int argc , char *argv[])
{
    pthread_t writer_t, reader_t;

    queue_t = (struct Queue*) malloc(sizeof(Queue));
    queue_t->head = 0;
    queue_t->tail = 0;

    sem_init(&queue_t->empty, 0, QUEUE_SIZE);
    sem_init(&queue_t->full, 1, 0);

    int shmid;
    key_t key; 
    key =3434;

    //Create the segment and set permissions.
    if ((shmid = shmget(key, sizeof(struct shared_mem), IPC_CREAT | 0666)) < 0)
    {
        perror("shmget error");
        if(errno==EEXIST)
        {
            fprintf(stderr,"shared memory exist... ");
            exit(1);
        }
    }
    fprintf(stdout,"shared mem created with id: %d\n",shmid);

    if( pthread_create( &reader_t , NULL , reader_thread , &shmid) < 0)
    {
        perror("could not create reader thread");
        return 1;
    }
    puts("reader thread assigned"); 

    if( pthread_create( &writer_t , NULL , writer_thread , NULL) < 0)
    {
        perror("could not create writer thread");
        return 1;
    }
    puts("writer thread assigned");

    pthread_join(reader_t, NULL);
    pthread_join(writer_t, NULL);

    shmctl(shmid,IPC_RMID,NULL);

    return 0;
}


//---------
void *reader_thread(void * id)
{
    char imgPath[100];
    FILE *image_fd;
    char * img_filename;
    char imgBuf[1024];
    int readed_img_data;
    char imgcount[10];
    char * shm_addr;
    int shm_id = *((int *)id);

    shared = (struct shared_mem *) shmat(shm_id, NULL, 0);
    if ((int) shared == -1)
    {
        printf("*** shmat error (server) ***\n");
        exit(1);
    }
    memset(shared, 0, sizeof(struct shared_mem));
    sem_init(&shared->shm_sem, 1, 1);
    shared->read_client = 0;
    shared->client_id = 1;
    //printf("shared address: %s", &shared);

    while (1)
    {   
        printf("Here in thread reader!\n");
        sem_wait(&queue_t->full);
        sem_wait(&shared->shm_sem);
        if (queue_t->tail != queue_t->head)
        {
            memmove(imgPath,queue_t->imgAddr[queue_t->head],strlen(queue_t->imgAddr[queue_t->head])-1);
            imgPath[strlen(queue_t->imgAddr[queue_t->head])-1] = '\0';
            queue_t->head = (queue_t->head + 1) % QUEUE_SIZE;
        }   
        sem_post(&queue_t->empty);
        printf("imagepath size: %d...\n",sizeof(imgPath));  

        memcpy(&shared->imgDir, &imgPath, sizeof(imgPath));   
        printf("shared contents: %s\n",(char *) &shared->imgDir);
        shared->read_client = 0;
        sem_post(&shared->shm_sem);  
    } //end while
    if(shmdt(shm_addr) != 0)
        fprintf(stderr, "Could not close memory segment.\n"); 
    return 0;
}

clientSide():

typedef struct shared_mem {
    char imgDir[100];
    int client_id;
    int read_client;
    sem_t shm_sem;
}shared_mem;
shared_mem *shared;

int main(int argc , char *argv[])
{
    char server_data[1024];
    int server_data_len = 1024;
    char imgDir[100]= "client_/";   // directory where client store image
    char imgPath[100];  // image address which client pop from shared memory    
    char *imgFilename;
    char imgcount[10] = "";
    int readed_img_data;
    int shmid;
    key_t key;

    key = 3434;

    shmid = shmget(key, sizeof(struct shared_mem), 0666);
    printf("get shmid: %d\n ", shmid);
    if ((shared = (struct shared_mem *) shmat(shmid, NULL, 0)) == (void *) -1) 
    {
        perror("shmat error");
        return 1;
    }
    shared->client_id = 0;
    sprintf(imgDir,"%s", shared->imgDir);

    //keep communicating with server
    while(1)
    {
        printf("\nReceiving new file...\n");
        sem_wait(&shared->shm_sem);
        memcpy(&imgPath, &shared->imgDir, 100);
        memcpy(&read_client, &shared->read_client, 4);
        if (read_client == 0)
            read_client = 1;
        memcpy(&shared->read_client, &read_client, 4);
        sem_post(&shared->shm_sem);

        FILE * Client_img = fopen(imgPath,"r");
        if (!Client_img)
            printf("%s not created!", imgPath);

        fseek(Client_img, 0, SEEK_END); // seek to end of file
        long size = ftell(Client_img); // get current file pointer
        rewind(Client_img);
        printf("size: %ld", size);

        imgFilename= strrchr(imgPath,'/');
        if(imgFilename)
            ++imgFilename;
        else
        {
            imgFilename = (char*)malloc(100 * sizeof(char));
            memmove(imgFilename,imgPath, strlen(imgPath));
        }
        strcat(imgDir, imgFilename);
        printf("imgDir:%s", imgDir);

        FILE * written_img = fopen(imgDir, "wa");
        int read_sz = fread(server_data, sizeof(char), size, Client_img);
        int write_sz = fwrite(server_data, sizeof(char), read_sz, written_img);
        fclose(Client_img);
        fclose(written_img);
    }//while
    if(shmdt(shm) != 0)
        fprintf(stderr, "Could not close memory segment.\n");
    return 0;
}