客户端在连接到共享内存时会出现分段错误

时间:2014-07-16 07:43:41

标签: c synchronization segmentation-fault semaphore shared-memory

您好我想实现一个客户端 - 服务器程序,它通过共享内存相互通信。 在服务器端我有两个线程。作家线程和读者线程。写入程序线程将一些数据放入队列,读取器线程从中读取数据并通过共享内存将数据传递到客户端。具有shmid的客户端可以将自身附加到其上并从中读取数据...

现在,当连接到共享内存时,我在客户端遇到分段错误。

这是我的代码:

服务器端:

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;
}

客户机侧():

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;
}

0 个答案:

没有答案