Komunikacja poprzez pamięc dzieloną

0

Cześć. Mam program do komunikacji międzyprocesowej, tworzący segment pamięci dzielonej pozwalający zapisywać i odczytywać komunikaty.

Mam problem z dodaniem opcji żeby moje komunikaty zapisywały się w tablicy w segmencie pamięci dzielonej w taki sposób:

  • zapisz k "komunikat" - zapisz komunikat w wierszu k tablicy stringów w pamięci dzielonej,
  • odczytaj k - odczytaj komunikat z wiersza k tablicy w pamięci dzielonej.

[cpp]#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>

#define SEGSIZE 100

main( int argc, char * argv[] )
{
int shmid, cntr;
char * segptr;

/* Jeśli nie wpisano parametru przejdź do usage() */
if( argc == 1 )
     usage();

/* utwórz unikalny klucz poprzez wywołanie ftok() */
key_t key;
key = ftok( ".", 'S' );

/* otwórz segment pamięci dzielonej - utwórz jeżeli trzeba; nadanie praw do segmentu */
if(( shmid = shmget( key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666 ) ) == - 1 )
{
    printf( "Segment pamięci dzielonej istnieje - otwieram jako klient\n" );
   
    /* Segment prawdopodobnie istnieje - próbuję otworzyć jako klient */
    if(( shmid = shmget( key, SEGSIZE, 0 ) ) == - 1 )
    {
        perror( "shmget" );
        exit( 1 );
    }
}
else
{
    printf( "Tworzenie nowego segmentu pamięci dzielonej\n" );
}

/* Podłącz segment pamięci dzielonej do tego procesu */
if(( segptr = shmat( shmid, 0, 0 ) ) == - 1 )
{
    perror( "shmat" );
    exit( 1 );
}
/* Wybór funkcji zapisu/odczytu ze zmianą dużej litery na małą */
switch( tolower( argv[ 1 ][ 0 ] ) )
{
case 'z': writeshm( shmid, segptr, argv[ 2 ] );
    break;
case 'o': readshm( shmid, segptr );
    break;
    /* Jeśli wybrano zły parametr przechodzi do usage() */
    default: usage();
   
}

}
/* Zapisuje w pamięci wpisany text /
writeshm( int shmid, char * segptr, char * text )
{
strcpy( segptr, text );
printf( "Zrobiono...\n" );
}
/
Zwraca na stdout wartości zapisane w pamięci */
readshm( int shmid, char * segptr )
{
printf( "segptr: %s\n", segptr );
}

/* Wyświetla schemat prawidłowego wywołania programu */
usage()
{
fprintf( stderr, "Program do komunikacji międzyprocesowej\n" );
fprintf( stderr, "\nPOSTAĆ WYWOŁANIA: <nazwa programu="programu"> (z)apisz <text>\n" );
fprintf( stderr, " (o)dczytaj\n" );

exit( 1 );

}[/cpp]

Jak to rozwiązać?

0

Nie spełniłeś warunków zadania. Program jako taki działa, ale musisz sobie podzielić przydzieloną pamięć na n wierszy po np. 256 bajtów i w zależności od polecenia (zapis/odczyt i k) pobierać dane lub zapisywać (strlcpy / strncpy) dane od użytkownika.

P.s.: strcpy( segptr, text ); Co się stanie, jak user poda w Twoim programie więcej niż 100-bajtowy tekst?

0

Zacząłem kombinować w ten sposób

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>

#define SEGSIZE 1000
#define NUMSEGS 20



main( int argc, char * argv[] )
{
    int shmid;
   char *segptr[NUMSEGS];
int k = argv[ 2 ];

    /* Jeśli nie wpisano parametru przejdź do usage() */
    if( argc == 1 )
         usage();
   
    /* utwórz unikalny klucz poprzez wywołanie ftok() */
    key_t key;
    key = ftok( ".", 'S' );
   
    /* otwórz segment pamięci dzielonej - utwórz jeżeli trzeba; nadanie praw do segmentu */
    if(( shmid = shmget( key, SEGSIZE, IPC_CREAT | IPC_EXCL | 0666 ) ) == - 1 )
    {
        printf( "Segment pamięci dzielonej istnieje - otwieram jako klient\n" );
       
        /* Segment prawdopodobnie istnieje - próbuję otworzyć jako klient */
        if(( shmid = shmget( key, SEGSIZE, 0 ) ) == - 1 )
        {
            perror( "shmget" );
            exit( 1 );
        }
    }
    else
    {
        printf( "Tworzenie nowego segmentu pamięci dzielonej\n" );
    }
   
    /* Podłącz segment pamięci dzielonej do tego procesu */
    if(( segptr[NUMSEGS] = shmat( shmid, 0, 0 ) ) == - 1 )
    {
        perror( "shmat" );
        exit( 1 );
    }

    /* Wybór funkcji zapisu/odczytu ze zmianą dużej litery na małą */

    switch( tolower( argv[ 1 ][ 0 ] ) )
    {
   
	case 'z': 
		strcpy( segptr[k], argv[ 3 ] );
		printf( "Zrobiono... \n");
        break;
    

	case 'o': 
		printf( "segptr: %s\n", segptr );
	break;
        
	/* Jeśli wybrano zły parametr przechodzi do usage() */
        default: usage();
       
    }
}

/* Wyświetla schemat prawidłowego wywołania programu */
usage()
{
    fprintf( stderr, "Program do komunikacji międzyprocesowej\n" );
    fprintf( stderr, "\nPOSTAĆ WYWOŁANIA:  <nazwa programu> (z)apisz <text>\n" );
    fprintf( stderr, "     				(o)dczytaj\n" );
   
    exit( 1 );
}

Jednak niestety nie działa.

0

Źle inicjalizujesz pamięć pointery. Ta linijka jest źle:

  if(( segptr[NUMSEGS] = shmat( shmid, 0, 0 ) ) == - 1 )

Podstawy z C proszę Pana. Musisz i-temu wskaźnikowi z tablicy segptr[] przypisać adres uzyskany od shmat przesunięty o rozmiar wiersza. To powinno spowodować, że zacznie to z powrotem działać.

Edit:
strcpy to headshot. Wyrób sobie nawyk używania strncpy (lub lepiej: strlcpy).

1 użytkowników online, w tym zalogowanych: 0, gości: 1