2010-05-11 5 views
0

Je souhaite créer une application de conversation de base en C à l'aide de la mémoire partagée. Je travaille sous Linux. L'application consiste à écrire le client et le serveur peut lire, et si le serveur écrit le client peut lire le message.Programme de mémoire partagée de base en C

J'ai essayé de le faire, mais je n'arrive pas à établir la communication entre le client et le serveur. Le code est le suivant:

server.c

int 
main(int argc, char **argv) 
{ 
char *msg; 
static char buf[SIZE]; 
int n; 

msg = getmem(); 
memset(msg, 0, SIZE); 
initmutex(); 

while (true) 
{ 
    if((n = read(0, buf, sizeof buf)) > 0) 
    { 
    enter(); 
    sprintf(msg, "%.*s", n, buf); 
    printf("Servidor escribe: %s", msg); 
    leave(); 
    }else{ 
    enter(); 
    if (strcmp(buf, msg)) 
    { 
    printf("Servidor lee: %s", msg); 
    strcpy(buf, msg); 
    } 
    leave(); 
    sleep(1); 
    } 
} 
return 0; 
} 

client.c

int 
main(int argc, char **argv) 
{ 
char *msg; 
static char buf[SIZE-1]; 
int n; 

msg = getmem(); 
initmutex(); 

while(true) 
{ 
    if ((n = read(0, buf, sizeof buf)) > 0) 
    { 
    enter(); 
    sprintf(msg, "%.*s", n, buf); 
    printf("Cliente escribe: %s", msg); 
    leave(); 
    }else{ 
    enter(); 
    if (strcmp(buf, msg)) 
    { 
    printf("Cliente lee: %s", msg); 
    strcpy(buf, msg); 
    } 
    leave(); 
    sleep(1); 
    } 
} 
printf("Cliente termina\n"); 
return 0; 
} 

Le module de mémoire partagée est le folowing:

#include "common.h" 

void 
fatal(char *s) 
{ 
perror(s); 
exit(1); 
} 

char * 
getmem(void) 
{ 
int fd; 
char *mem; 

if ((fd = shm_open("/message", O_RDWR|O_CREAT, 0666)) == -1) 
    fatal("sh_open"); 
ftruncate(fd, SIZE); 
if (!(mem = mmap(NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))) 
    fatal("mmap"); 
close(fd); 
return mem; 
} 

static sem_t *sd; 

void 
initmutex(void) 
{ 
if (!(sd = sem_open("/mutex", O_RDWR|O_CREAT, 0666, 1))) 
    fatal("sem_open"); 
} 

void 
enter(void) 
{ 
sem_wait(sd); 
} 

void 
leave(void) 
{ 
sem_post(sd); 
} 
+0

S'il vous plaît formater votre code correctement (ou le télécharger sur un pastebin comme [privatepaste] (https://c.privatepaste.com)). – ThiefMaster

+0

Dites-nous également ce qui se passe lorsque vous essayez d'exécuter notre code. –

Répondre

3

Au moment où vous travaillerez correctement, vous aurez réinventé un tuyau. Une socket est la meilleure solution, qui couvrira également le scénario le plus courant où le serveur et le client ne s'exécutent pas sur la même machine.

1
/* client */ 
#include <stdio.h> 
#include <string.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <sys/shm.h> 

#define SIZEOFSHMSEG 50   /* Size of the shared mem segment */ 

#include<stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include<fcntl.h> 
#define PORT  6002 

int main() 
{ char buffer[512]; 
    int rc, shmid, i,l,choice,n; 
    void *shm_address; 
    struct shmid_ds shmid_struct; 
char c,ch; 
    char HOST[30]; 
char hostname[100]; 
int sd; 
struct sockaddr_in sin; 
struct sockaddr_in pin; 
struct hostent *hp; 

printf("enter the server's ip address:"); 
scanf("%s",HOST); 
n=strlen(HOST); 
HOST[n]='\0'; 


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

/* fill in the socket structure with host information */ 
memset(&pin, 0, sizeof(pin)); 
pin.sin_family = AF_INET; 
pin.sin_addr.s_addr = inet_addr(HOST); 
pin.sin_port = htons(PORT); 


/* connect to PORT on HOST */ 
if (connect(sd,(struct sockaddr *) &pin, sizeof(pin)) == -1) { 
    perror("connect"); 
    exit(1); 
} 

    /* shared memory setup */ 
    shmid = shmget(2222, SIZEOFSHMSEG, 0666 | IPC_CREAT | IPC_EXCL); 
    if (shmid == -1) 
     { 
     printf("main: shmget() failed\n"); 
     return -1; 
     } 

    /* Attach the shared memory segment to the server process.  */ 
    shm_address = shmat(shmid, NULL, 0); 
    if (shm_address==NULL) 
     { 
     printf("main: shmat() failed\n"); 
     return -1; 
     } 
fcntl(sd, F_SETFL, O_NONBLOCK); 
buffer[0]='\0'; 
strcpy((char *)shm_address,buffer); 
for(;;) 
{ 
    printf("----------------------------------------------------------\n"); 
    printf("1.read from shared mem\n2.write to shared area\n3.exit\n"); 
    printf("ur choice:"); 
    scanf("%d",&choice); 

    n = read(sd, buffer, 512); 
    buffer[n] = '\0'; 
    strcpy((char *) shm_address, buffer); 

    if(choice==1) 
    { strcpy(buffer,(char *)shm_address); 
    printf("display:%s\n",buffer); 
    } 

    if(choice==2) 
    { printf("enter the data:"); 

    scanf(" %[^\n]",buffer); 
    n=strlen(buffer); 
    buffer[n]='\0'; 
    strcpy((char *) shm_address, buffer); 
    write(sd, buffer, strlen(buffer)); 
    } 

    if(choice==3) 
         { printf("terminated\n"); 
    break; 
    } 
    printf("----------------------------------------------------------\n"); 
} 
close(sd); 
rc = shmdt(shm_address); 
    if (rc==-1) 
     { 
     printf("main: shmdt() failed\n"); 
     return -1; 
     } 
    rc = shmctl(shmid, IPC_RMID, &shmid_struct); 
    if (rc==-1) 
     { 
     printf("main: shmctl() failed\n"); 
     return -1; 
     } 
return 0; 
} 
1
/* server */ 
#include <stdio.h> 
#include <string.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 

#define SIZEOFSHMSEG 50   /* Size of the shared mem segment */ 

#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 

#include<fcntl.h> 
#define PORT 6002 

int main() 
{ char buffer[512]; 
    int rc, shmid, i,l,choice,n; 
    void * shm_address; 
    struct shmid_ds shmid_struct; 
char c; 

int sd, sd_current, cc; 
int addrlen; 
struct sockaddr_in sin; 
struct sockaddr_in pin; 

/* get an internet domain socket */ 
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("socket"); 
    exit(1); 
} 

/* complete the socket structure */ 
memset(&sin, 0, sizeof(sin)); 
sin.sin_family = AF_INET; 
sin.sin_addr.s_addr = htonl(INADDR_ANY); 
sin.sin_port = htons(PORT); 

/* bind the socket to the port number */ 
if (bind(sd, (struct sockaddr *) &sin, sizeof(sin)) == -1) { 
    perror("bind"); 
    exit(1); 
} 

/* show that we are willing to listen */ 
if (listen(sd, 5) == -1) { 
    perror("listen"); 
    exit(1); 
} 

printf("waiting for client....\n"); 

addrlen = sizeof(pin); 
if ((sd_current = accept(sd, (struct sockaddr *) &pin, &addrlen)) == -1) { 
    perror("accept"); 
    exit(1); 
} 
printf("connected..\n"); 

/* shared memory setup */ 
    shmid = shmget(1111, SIZEOFSHMSEG, 0666 | IPC_CREAT | IPC_EXCL); 
    if (shmid == -1) 
     { 
     printf("main: shmget() failed\n"); 
     return -1; 
     } 

    /* Attach the shared memory segment to the server process.  */ 
    shm_address = shmat(shmid, NULL, 0); 
    if (shm_address==NULL) 
     { 
     printf("main: shmat() failed\n"); 
     return -1; 
     } 
buffer[0]='\0'; 
strcpy((char *)shm_address,buffer); 

fcntl(sd_current, F_SETFL, O_NONBLOCK); 
for(;;) 
{ 

    printf("----------------------------------------------------------\n"); 
    printf("1.read from shared mem\n2.write to shared area\n3.exit\n"); 
    printf("ur choice:"); 
    scanf("%d",&choice); 

    n=read(sd_current, buffer, 512); 
    buffer[n] = '\0'; 
    strcpy((char *) shm_address, buffer); 

    if(choice==1) 
    { strcpy(buffer,(char *)shm_address); 
    printf("display:%s\n",buffer); 
    } 

    if(choice==2) 
    { printf("enter the data:"); 
    scanf(" %[^\n]",buffer); 
    n=strlen(buffer); 
    buffer[n]='\0'; 

    strcpy((char *) shm_address, buffer); 
    write(sd_current, buffer, strlen(buffer)); 
    } 
    if(choice==3) 
         { printf("terminated\n"); 
    break; 
    } 
    printf("----------------------------------------------------------\n"); 
} 
close(sd_current); 
close(sd); 
rc = shmdt(shm_address); 
    if (rc==-1) 
     { 
     printf("main: shmdt() failed\n"); 
     return -1; 
     } 
    rc = shmctl(shmid, IPC_RMID, &shmid_struct); 
    if (rc==-1) 
     { 
     printf("main: shmctl() failed\n"); 
     return -1; 
     } 
return 0; 
} 
Questions connexes