Komunikacja Klient-Serwe. Cwiczenie. C

0

Witam. Na ćwiczenia w szkole mam do wykonania program w C. Zatrzymałem sie na pewnym etapie i potrzebuje pomocy by ruszyć dalej.
Program w obecnej formie jest to klient (qk.c) oraz serwer (qs.c). Serwer to prosta grafika, klient wysyła komunikaty(jedna znak kilkukrotnie) które maja pojawiać sie w losowych miejscach (tak jakby poruszanie się) na serwerze. I to chodzi. Problem zaczyna się gdy prowadzący kazał zrobić skrypt który wywołuje kilku klientów, którzy wysyłają komunikaty do kolejki, a na serwerze porusza się tak jakby kilka klientów jednocześnie.

Czy ktoś jest w stanie poprawić mój kod, lub powiedzieć jak to wykonać ???

Klient

#include <stdio.h>
#include <stdlib.h>
#include  <errno.h>
#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/msg.h>
#include  <sys/sem.h>
#include  <sys/shm.h>
#include  <signal.h>


#define PERM  0666     // prawa dostepu
#define KLUCZ_KOM   (key_t)1231

//---- struktura dla komunikatow ----
      
struct Komunikat {
  long typ;
  char z1;
}; 
 

 int main(int argc, char *argv[]) {
 
  int kom, kon, i, ik, czas; 
  struct Komunikat msg; 
  //if (argc<3) {
    //printf("\n Brak argumentow :  znak, ilosc komunikatow , odstep czasu\n\n");
    //exit(1);
  //}   
  if ((kom=msgget(KLUCZ_KOM, 0))==-1) {
    perror("\n     K.msgget error  ");
    exit(-1);
  }
     
 msg.z1=*argv[1]; 

    msg.typ=2; 
    ik=10;      // ilosc komunikatow
    //czas=1;    // odstep czasu
    for (i=1;i<=ik;i++) {
      //sleep(czas);
      if ((msgsnd(kom, &msg, sizeof(msg),0)) == -1) {
         perror("\n    K.Awaria serwera  ");
         exit(-1);
      }
          
    }
    printf("\n\nKoniec pracy Klienta \n\n");
  exit (0); 
} 

Serwer

 #include  <unistd.h>
#include  <stdlib.h>
#include  <stdio.h>
#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/msg.h>
#include  <signal.h>
#include  <ncurses.h>

#include <time.h>

#define PERM  0660     // prawa dostepu
#define KLUCZ_KOM   (key_t)1231

//---- struktura dla komunikatow ----
      
struct msgbuf {
  long typ;
  char z1;
};  
int w=15,v=15;
 int kom, kon; 
void losuj() 
{
	srand( time(0));
	int j=(rand()%3)-1;
	sleep(1);
	srand( time(0));
	int i=(rand()%3)-1;
	if (j==0 && i==0)
	{  srand( time(0));
	   j=(rand()%3)-1;
	}
	w=w+(j);
	v=v+(i);
}
void koniec() {
  msgctl(kom, IPC_RMID, 0);
  
  curs_set(1);
  clear();
  refresh();
  endwin();

  printf("\n      Ctrl_C Serwera\n");
  exit(0);
} 

 int main(void) {
 
 
  struct msgbuf msg;
  
  signal(SIGINT, koniec); 
  
  initscr();
  curs_set(0);
  start_color();
  clear();

//-------------------------------------------


  
  
  if ((kom=msgget(KLUCZ_KOM, PERM | IPC_CREAT))==-1) {
     perror("\n     S.msgget error\n");
     exit(-1);
  }   
init_pair(1,COLOR_RED,COLOR_BLACK);			// czerwone na czarnym 
  init_pair(2,COLOR_BLACK,COLOR_RED);  		// czarne na  czerwonym
  init_pair(3,COLOR_WHITE,COLOR_BLACK);
  		// biale na czarnym
  init_pair(4,COLOR_GREEN,COLOR_BLACK);
 		// zielone na czarnym
  init_pair(5,COLOR_BLUE,COLOR_BLACK);
 
 

  attrset(COLOR_PAIR(3) | (A_BOLD));
  move(5,6); printw("__________________________");
  attrset(COLOR_PAIR(5) | (A_BOLD)); 
  move(8,6); printw("~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  attrset(COLOR_PAIR(3) | (A_BOLD ));        
  move(10,6); printw("__________________________");
  attrset(COLOR_PAIR(3) | (A_BOLD )); 
  move(1,32); printw("|       |");
  move(2,32); printw("|       |");
  move(3,32); printw("|       |");
  move(4,32); printw("|       |");
  move(5,32); printw(",       ,");
  move(5,41); printw("__________________________");
  attrset(COLOR_PAIR(5) | (A_BOLD)); 
  move(8,40); printw("~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  attrset(COLOR_PAIR(3) | (A_BOLD ));        
  move(10,41); printw("__________________________");
  move(10,32); printw(",       ,");
  move(11,32); printw("|       |");
  move(12,32); printw("|       |");
  move(13,32); printw("|       |");
  move(14,32); printw("|       |");

  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(9,14); printw("=");
  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(9,12); printw("[8");
  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(9,15); printw("8}");

  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(7,45); printw("=");
  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(7,43); printw("{8");
  attrset(COLOR_PAIR(4) | (A_BOLD ));
  move(7,46); printw("8]");
 //move(18,18); printw("================================");
 //move(19,18); printw("================================");
 //move(20,18); printw("================================");
 //move(21,18); printw("================================");
 //move(22,18); printw("================================");
 //move(23,18); printw("================================");
   refresh();

	
  kon=1;
  while(kon){
	move(w,v); printw(" ");
	
	
	
    if ((msgrcv(kom,&msg,sizeof(msg),0 ,0))==-1) {
      perror("\n    S.msgrcv error  ");
      kon=0; 
    } else {
      switch(msg.typ) {
        case 2:
	losuj();
	    move(w,v);
            printw("%c",msg.z1);
           
	    refresh();  
            break;
        
        default:
            break; 
      }
    }    
  } 
 
 
 // sleep(2);
   
  msgctl(kom, IPC_RMID, 0);
  curs_set(1);
  clear();
  refresh();
  endwin();

  printf("\nKoniec pracy Serwera\n");
  return (0); 
}
0

Nie lepiej Ci zrobić to na gniazdach?
W sumie nic nie mam do "message queues", ale w rezultacie w internetach masz więcej przykładów.

0

Tak prowadzący kazał robić, to nie jest mój wybór;)

0

No to masz 2 rozwiązania swojego problemu:

  1. Albo użyjesz wątków do odbierania danych (moze być fork):
    #jeden watek na wyswietlanie
    #drugi na odbior danych
  2. Ewentualnie po jednym wątku dla odebranych danych - aby wyświetlić (czyli dzielone okno konsoli).
  3. Mozesz zrobić cyklicznie, czyli:
    a) odbierasz aż kolejka będzie pusta
    b) wyswietlasz wszystko co masz, powiedzmy w liście
    c) skaczesz do punktu a)

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