Scambio messaggi (half duplex) tra client e server

di il
3 risposte

Scambio messaggi (half duplex) tra client e server

Salve a tutti, dovrei fare un'esercizio assegnatomi dal professore in cui un client e un server si scambiano messaggi fino a quando non si preme un tasto per terminare la conversazione.
Ho provato ad implementare lo scambio di messaggi ma dopo essersi inviato un messaggio, la comunicazione termina..mi potreste far capire dove sbaglio per piacere?
A seguire c'e l'implementazione del client:


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define PROTOPORT  5193  /* default port number */

extern  int  errno;
char localhost[] = "127.0.0.1"; /* default host name */

int main(int argc, char *argv[]) {
  struct  sockaddr_in sad; /* structure to hold an IP address     */
  int     sd;              /* socket descriptor                   */
  int     port;            /* protocol port number                */
  int     n;               /* number of characters read           */
  char    buf[1000];       /* buffer for storing data from the server     */
  char    *host;	
  int     status = 1;       /*status = write*/


  memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure   */
  sad.sin_family = AF_INET;         /* set family to Internet       */
  
  if (argc > 2) {                   /* if protocol port specified   */
    port = atoi(argv[2]);           /* convert to binary            */
  } else {
    port = PROTOPORT;               /* use default port number      */
  }
  if (port > 0)                     /* test for legal value         */
    sad.sin_port = htons((u_short)port);
  else {                            /* print error message and exit */
    fprintf(stderr,"bad port number %s\n",argv[2]);
    exit(1);
  }

  /* Check host argument and assign host name. */
  if (argc > 1) {
    host = argv[1];    /* if host argument specified   */
  } else {
    host = localhost;
  }

  sad.sin_addr.s_addr = inet_addr(host);
  
  /* Create a socket. */
  sd = socket(PF_INET, SOCK_STREAM, 0);
  if (sd < 0) {
    fprintf(stderr, "socket creation failed\n");
    exit(1);
  }	  
 
  if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
    fprintf(stderr, "connect failed\n");
    exit(1);
  }
  switch(status) {
    case 1:
      printf("(CLIENT) Scrivi il messaggio: ");
      fgets(buf,999, stdin); /*legge una linea dallo standard output*/
      n = write(sd, buf, sizeof(buf));
      status = 2;
      break;
    case 2:
      n = read(sd, buf, sizeof(buf));
      printf("(CLIENT) Ecco il messaggio ricevuto dal server: %s\n", buf);
      status = 1;
      break;
    }
  close(sd);
  /* Terminate the client program gracefully. */
  exit(0);
}

Implementazione del server:


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define PROTOPORT   5193 /* default protocol port number */
#define QLEN        6    /* size of request queue        */



int main(int argc, char *argv[]) {
  struct  sockaddr_in sad; /* s. to hold server's address  */
  struct  sockaddr_in cad; /* s. to hold client's address  */
  int     sd, sd2;         /* socket descriptors */
  int     port; 	       /* protocol port number */
  int     alen;      	   /* length of address  */
  char    buf[1000];       /* buffer for sending data */
  int     n;
  char    *messaggio_ricevuto = "FINE COMUNICAZIONE";
  int     status = 2;
	
  memset((char *)&sad, 0, sizeof(sad)); 	/* clear sockaddr s. */
  sad.sin_family = AF_INET;  		        /* set family to Internet */
  sad.sin_addr.s_addr = htonl(INADDR_ANY);	/* set the local IP addr  */
  
  if (argc > 1) { 		                    /* if argument specified        */
     port = atoi(argv[1]);   		        /* convert argument to binary   */
   } else {
     port = PROTOPORT;       		        /* use default port number      */
   }

   /* Verify port number */
   /* … */

  sad.sin_port = htons((u_short)port);
   
  /* Create a socket */
  sd = socket(PF_INET, SOCK_STREAM, 0);
  
  if (sd < 0) {
	 fprintf(stderr, "socket creation failed\n");
	 exit(1);
  }
  /* Bind a local address to the socket */
  if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
     fprintf(stderr,"bind failed\n");
     exit(1);
  }
  /* Specify the size of the request queue */
  if (listen(sd, QLEN) < 0) {
     fprintf(stderr,"listen failed\n");
     exit(1);
  }
  while((sd2 = accept(sd, (struct sockaddr *)&cad, &alen)) > -1) {
    switch(status) {
      case 1:
        printf("(SERVER) Scrivi il messaggio: ");
        fgets(buf, 999, stdin);
        n = write(sd2, buf, sizeof(buf));
        status = 2;
        break;
      case 2 :
        n = read(sd2, buf, sizeof(buf));
    printf("(SERVER) Ecco il messaggio ricevuto dal client: %s\n", buf);
    status = 1;
    break;
  }
  close (sd2);
   }}


Grazie in anticipo a chiunque mi risponderà

3 Risposte

  • Re: Scambio messaggi (half duplex) tra client e server

    A prima vista mi sembra che nel client manchi un ciclo in cui dovrebbe essere eseguito lo switch, altrimenti viene chiusa la comunicazione subito dopo il primo invio.
  • Re: Scambio messaggi (half duplex) tra client e server

    Grazie Oregon per la risposta.
    Quindi siccome l'esercizio chiede che lo scambio di messaggi avvenga finquando non si preme ad esempio q per uscire, mi converrebbe fare una cosa del genere:
    while(finquando non premie q per uscire) {
    esegui lo switch
    }

    giusto?
  • Re: Scambio messaggi (half duplex) tra client e server

    Oregon ho fatto in questo modo:

    per quanto riguarda il lato client ho aggiunto il ciclo while in questo modo
    while(status != 0) {
    
      switch(status) {
        case 1:
          printf("(CLIENT) Scrivi il messaggio: ");
          fgets(buf,999, stdin); /*legge una linea dallo standard output*/
          n = write(sd, buf, sizeof(buf));
          status = 2;
          break;
        case 2:
          n = read(sd, buf, sizeof(buf));
          printf("(CLIENT) Ecco il messaggio ricevuto dal server: %s\n", buf);
          status = 1;
          break;
        }}

    per il server invece:
    while((sd2 = accept(sd, (struct sockaddr *)&cad, &alen)) > -1) {
        while(status != 0) {
        switch(status) {
          case 1:
            printf("(SERVER) Scrivi il messaggio: ");
            fgets(buf, 999, stdin);
            n = write(sd2, buf, sizeof(buf));
            status = 2;
            break;
          case 2 :
            n = read(sd2, buf, sizeof(buf));
        printf("(SERVER) Ecco il messaggio ricevuto dal client: %s\n", buf);
        status = 1;
        break;
    e adesso riescono a comunicare in maniera half-duplex ^_^ però ora il problema è che dovrei interrompere la comunicazione ad esempio digitando un carattere q ho fatto un paio di prove ma non ci riesco... hai qualche suggerimento?
Devi accedere o registrarti per scrivere nel forum
3 risposte