[C]Invio/ricezione/elaborazione stringhe con le socket

di Anonimizzato18393 il
12 risposte
Qui di seguito il codice di un programma per inviare e ricevere stringhe tra un client ed un server. Dopo uno scambio di frasi per indicare il successo dell'avvenuta connessione, il client invia una stringa al server, il quale rimuove le vocali e la reinvia al client. Il problema principale è che aggiunge caratteri che non c'entrano al termine della mia stringa.
So che da qualche parte ci sono errori sulle terminazioni con lo 0 e le lunghezze, ma le sto provando tutte e sto nel pallone. Dove sbaglio?
**SERVER SIDE**

#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 il client\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 STRINGA DAL CLIENT

    char str1[BUFSIZE+1]; char str1des[BUFSIZE+1];
    int i,j=0;

    //recv (Csocket, str1, BUFSIZE - 1, 0);

    int read = recv(Csocket, str1, BUFSIZE-1, 0); str1[read] = '\0';


//-------------------------------ELIMINAZIONE VOCALI DALLA STRINGA RICEVUTA

    for(i=0;i<=strlen(str1)+1;i++) {

        if(str1[i]=='a'||str1[i]=='e'||str1[i]=='i'||str1[i]=='o'||str1[i]=='u' ||str1[i]=='A'||str1[i]=='E'||str1[i]=='I'||str1[i]=='O'||str1[i]=='U')
                        str1[i]=' ';
                else
                        str1des[j++]=str1[i];
            }

            str1des[j]='\0';

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

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

}

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

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

}

**CLIENT SIDE**

#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

   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);


//------------------------------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+1];

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

if (read <=0) {

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

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


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

char str1[BUFSIZE+1]; int stringlen = strlen(str1);
printf ("inserisci prima stringa:\n");
scanf ("%s", str1);

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

//------------------------------RICEZIONE STRINGA ELABORATA DAL SERVER

char buf2[BUFSIZE+1];

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

if (read2 <=0) {

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

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

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

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

}

12 Risposte

  • Quando utilizzi buf2 e read2 nell'aggiungere il carattere '\0' usi la variabile read e non la read2
  • Bene..ho corretto. Non appaiono più caratteri strani, però alcune parole le tronca e/o mi aggiunge un solo carattere finale che non c'entra.
    Ho corretto anche quest'altra parte separando la dichiarazione di stringlen

    char str1[BUFSIZE+1]; int stringlen;
    printf ("inserisci prima stringa:\n");
    scanf ("%s", str1);
    stringlen = strlen(str1);
    if (send(Csocket, str1, stringlen, 0) != stringlen) {

    Cos'altro ho sbagliato?
  • Intanto non dovresti aggiungere 1 all'indirce read2 e quindi dovrebbe essere

    buf2[read2] = 0;
  • Ok, mi sa che adesso funziona! un paio di domande:

    1) quando aggiungere generalmente i +1 e i -1 quando si lavora con le stringhe? (e quindi con i vettori)
    2)come fargli accettare anche parole separate da uno spazio, fermo restando l'eliminazione delle vocali

    Grazie mille.
  • 1) la domanda non ha senso ... dipende da quanto vale i e da cosa stai facendo

    2) perché già non lo fai?
  • La stringa viene elaborata solo finchè non trova uno spazio...forse al posto di scanf dovrei usare la gets() ?
  • Sì, meglio la fscanf
  • La fscanf non si usa con i files di txt?
  • La puoi usare anche da tastiera con stdin
  • Ho sostituito la scanf con fscanf (stdin, str1);
    Purtroppo il programma parte, ma compaiono tutti caratteri strani dopo l'eliminazione vocali...và usata necessariamente assieme a fprintf? Oppure c'è qualcos'altro che mi sfugge?
  • Intendevo la fgets .... non fscanf
  • Andato!
    Se io volessi inviare/riceve altre stringhe, come potrei procedere? Utilizzare altri buffer e diversi send() recv() o sarebbe meglio pulire i buffer utilizzati per riutilizzarli?
Devi accedere o registrarti per scrivere nel forum
12 risposte