您好我想实现一个客户端 - 服务器程序,它通过共享内存相互通信。 在服务器端我有两个线程。作家线程和读者线程。写入程序线程将一些数据放入队列,读取器线程从中读取数据并通过共享内存将数据传递到客户端。具有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;
}