[C] client/server con le socket - mantenere comunicazione aperta

Pubblicità

mark9

Nuovo Utente
Messaggi
45
Reazioni
3
Punteggio
24
Ho delle difficoltà nel capire come mantenere un server (realizzato con le soket in C) in ascolto. Ad esempio un programma in C richiedeva che dopo l'instaurazione della connessione tra client e server, il client inviasse un numero al server e quest'ultimo, se fosse stato minore di 100 inviava al client "continue", altrimenti "quit". Nel caso del "continue" il client richiedeva all'utente l'inserimento del numero da inviare al server. Tutto bene fin qui, ma quando chiedevo il reinserimento del numero al server non arrivava più niente e quindi non rispondeva più.
Non capisco dove sbaglio...le procedure send/recv le implemento sempre in un ciclo while (1), ma non vengono ripetute dopo essere state eseguite la prima volta.
Grazie per il supporto, come sempre.
 
@mark9 Ti dico continue, però inviaci il codice o tuttalpiù l'algoritmo che segui. Altrimenti parliamo a vuoto, non avendo capacità telepatiche. :rolleyes:
 
Ecco qui...quello che non riesco a fare è far ricevere nuovamente dal server il numero per elaborarlo di nuovo e ridare una risposta al client. Penso che mi manchi qualcosa nel server, non so...grazie.

Codice:
//---------------------------------------------------------------------------------***SERVER***

 #if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 30

void ClearWinSock() {
#if defined WIN32
    WSACleanup();
#endif
}

int main(void) {

//---------------------------INIZIALIZZAZIONE WSADATA

#if defined WIN32

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf ("Error at WSAStartup");
        return 0;
    }

#endif

//-------------------------------CREAZIONE SOCKET

  int Mysocket;
  Mysocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (Mysocket < 0) {
      printf("socket creation failed\n");
      return 0;
  }

  struct sockaddr_in sad;
  memset(&sad, 0, sizeof(sad));
  sad.sin_family = AF_INET;
  sad.sin_addr.s_addr = inet_addr ("127.0.0.1");
  sad.sin_port = htons (9888);

//------------------------ASSEGNAZIONE PORTA E IP ALLA SOCKET

if (bind(Mysocket, (struct sockaddr*) &sad, sizeof(sad)) <0) {
    printf ("bind() failed\n");
    closesocket(Mysocket);
    return 0;
}

//---------------------------SETTAGGIO SOCKET ALL'ASCOLTO

int qlen = 10;

if (listen (Mysocket, qlen) < 0) {

    printf("listen() failed\n");
    closesocket(Mysocket);
    return 0;
}

struct sockaddr_in cad;
int Csocket;
int clientlen;

//------------------------------ACCETTA LA CONNESSIONE

while (1) {

    printf("In attesa di un client con cui comunicare\n");
    memset(&cad, 0, sizeof(cad));
    clientlen = sizeof(cad);

    if((Csocket = accept(Mysocket, (struct sockaddr*) &cad, &clientlen)) < 0) {
        printf ("accept failed\n");
        closesocket(Mysocket);
        ClearWinSock();
        return 0;
    }

    printf("connesso con -localhost-\n");

//-----------------------------------------INVIO STRINGA AL CLIENT

    char* inputString = "connessione avvenuta";
    int stringlen = strlen(inputString);


    if (send(Csocket, inputString, stringlen, 0) != stringlen) {
        printf("client-send() sent a different number of bytes than expected");
        closesocket(Csocket);
        ClearWinSock();
        system ("pause");
        return 0;
    }

//------------------------------------RICEZIONE PRIMA STRINGA DAL CLIENT

    char str1[BUFSIZE]; int a;

    int read = recv(Csocket, str1, BUFSIZE-1, 0);

    str1[read] = '\0';

    a= atoi(str1);

    printf("client scrive %d \n", a);



    if (a<100) {

        char* sendmsg = "continua";

                int sendmsglen = strlen(sendmsg);
                send(Csocket, sendmsg, sendmsglen, 0);
    }

    else if (a>100) {

        char* sendmsg = "quit - uscita";

                int sendmsglen = strlen(sendmsg);
                send(Csocket, sendmsg, sendmsglen, 0);

    }


}


    printf ("\n");
    closesocket (Csocket);
    system ("pause");
    ClearWinSock();
    return 0;

}

//---------------------------------------------------------------------------------***CLIENT***

#if defined WIN32
#include <winsock2.h>
#else
#define closesocket close
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 30

void ClearWinSock() {
#if defined WIN32
    WSACleanup();
#endif
}

//-----------------------------INIZIALIZZAZIONE WSADATA

int main (void) {
#if defined WIN32

    WSADATA wsaData;
    int iResult = WSAStartup (MAKEWORD (2,2), &wsaData);

    if (iResult !=0) {
        printf ("error at WSASturtup\n");
        return 0;
        }

#endif

//--------------------------------CREAZIONE SOCKET

    int Csocket;

    Csocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (Csocket < 0) {

    printf ("socket creation failed");
    closesocket (Csocket);
    ClearWinSock();
    return 0;
    }

 //--------------------------COSTRUZIONE INDIRIZZO SERVER


    char ind[BUFSIZE];
    printf ("Inserisci indirizzo a cui connetterti\n");
    scanf ("%s", ind);

    int port;
    printf ("Inserisci porta a cui connetterti\n");
    scanf("%d", &port);


    struct sockaddr_in sad;
    memset (&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr (ind);
    sad.sin_port = htons (port);

//------------------------------CONNESSIONE AL SERVER

  if (connect(Csocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) {
      printf ("failed to connect\n");
      closesocket (Csocket);
      ClearWinSock();
      return 0;
  }

//-----------------------------RICEZIONE DATI DAL SERVER

  char buf[BUFSIZE];

  int read = recv (Csocket, buf, BUFSIZE - 1, 0);

if (read <=0) {

    printf ("Qualcosa non và!\n");
}

else {
    buf[read] = '\0';
    printf("Server scrive: %s\n", buf);
}

//----------------------------INVIO PRIMA STRINGA AL SERVER

int a; char astr[BUFSIZE];

do {

printf("inserisci un intero:\n");
scanf("%d", &a);

itoa(a, astr, 10);

int astrlen = strlen(astr);


if (send(Csocket, astr, astrlen, 0) != astrlen) {
    printf("client-send() sent a different number of bytes than expected");
    closesocket(Csocket);
    ClearWinSock();
    system ("pause");
    return 0;
}

//----------------------------RICEZIONE RISPOSTA SERVER

char buf2[BUFSIZE];

  int read2 = recv (Csocket, buf2, BUFSIZE - 1, 0);

if (read <=0) {

    printf ("Qualcosa non và!\n");
}

else {
    buf[read] = '\0';
    printf("Server scrive: %s\n", buf2);
}

} while (a<100);


//---------------------------------------CHIUSURA CONNESSIONE

printf ("\n");
closesocket (Csocket);
system ("pause");
ClearWinSock();
return 0;

}
 
Ultima modifica da un moderatore:
Hai provato a farne il debugging? Hai provato con un network sniffer e.g. Wireshark per vedere cosa viene effettivamente mandato? Inoltre, ti consiglio di rivedere i valori di ritorno di send/recv: dovresti, tipicamente, gestire 3 casi, ma ne controlli uno solo.
 
A quanto pare ho risolto mettendo il recv() e relativo controllo del server in un do-while che faceva ripetere la ricezione finchè il numero ricevuto non fosse stato superiore a 100.

ps: comunque ho difficoltà con il debug di eclipse, mi indichereste una guida?
 
Ultima modifica:
Ciao, comincio nel dirti che il codice è strutturato molto male, difatti è inaccettabile che il controllo dell'accept ci sia ad ogni ciclo.
Ti conviene utilizzare un funzione che gestisca il tutto con un ciclo, e che quindi non venga fatto ogni volta la chiamata accept.
Se vuoi che il server accetti più di una connessione, esistono apposta i processi figli.
 
Pubblicità
Pubblicità
Indietro
Top