Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Aiuto socket c

    Salve a tutti avrei un problema da sottoporre:
    devo realizzare un semplice proxy HTTP/1.0 per scopi didattici,in C UNIX e
    con le librerie socket di berkeley(quelle classiche)
    e ho un problema con il codice che ho scritto:

    #include <netdb.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    char* proxy(char* request){
    int n;
    int sockfd, portno;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    error("ERROR opening socket",-1);
    server = gethostbyname("127.0.0.1");
    if (server == NULL) {
    error("ERROR, no such host\n",-1);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
    serv_addr.sin_port = htons(80);
    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    error("ERROR connecting",-1);
    char* response;
    response=calloc(40000000,sizeof(char));
    if(0)
    printf("\nRequest from host: %s",request);
    FullWrite(sockfd,request,strlen(request));
    FullRead(sockfd,response,39999999);
    printf("HTTP response received from server: \n%s",response);
    return response;
    }

    in finale response deve contenere l'header della risposta ottenuta dal server e il content della response,
    ovvero il corpo della risorsa richiesta.
    Per pagine html funziona benissimo, ma se una pagina ottenuta come response contiene delle immagini,
    il browser invia naturalmente per ognuna di esse una request dell'immagine al server,e
    le response relative a queste richiestye non vengono ricevute in maniera esatta,
    come si vede nello scambio request-response qui sotto.

    //----------------------inizio comunicazione
    GET http://localhost/wsdl_files/w3c_home.png HTTP/1.0
    Host: localhost
    User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050715 Firefox/1.0.6 SUSE/1.0.6-16
    Accept: image/png,*/*;q=0.5
    Accept-Language: it,it-it;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: close
    Proxy-Connection: close
    Referer: http://localhost/wsdl.htm


    HTTP/1.1 200 OK
    Date: Wed, 06 Sep 2006 13:39:43 GMT
    Server: Apache/1.3.37 (Unix)
    Last-Modified: Sat, 02 Sep 2006 18:00:13 GMT
    ETag: "20ab2-790-44f9c6ad"
    Accept-Ranges: bytes
    Content-Length: 1936
    Connection: close
    Content-Type: image/png

    PNG
    â–’
    //-------------fine comunicazione

    come si nota del corpo del file png vengono trasmessi solo pochi byte.
    Lo stesso succede utilizzando altri formati.
    Grazie anticipate a chi mi volesse aiutare.

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301

    Moderazione

    Aiuto socket c
    Cerca di usare titoli più significativi, come da Regolamento.

    Il titolo di questa discussione l'ho modificato io.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Mai lavorato col protocollo HTTP ma, andando a naso, credo che per ogni collegamento (quindi, per ogni tag href presente nel codice HTML) devrai mandare un nuovo comando GET per scaricarlo.
    Avrai quindi:
    socket --> send("GET / HTTP 1.0")
    ...per scaricare la home, e:
    socket --> send("GET /link.ext HTTP 1.0")
    ...per scaricare il file. Il tutto, ovviamente, usando il medesimo socket.

    Spero di non aver toppato.

    Saluti
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  4. #4
    alka, pardon per la mancanza ma come si nota non sono un grande partecipatore di forum...
    grazie comunque.

    ciao billiejoex forse non sono stato abbastanza chiaro, anzi sicuramente sono stato confusionale.
    quello che hai detto è giustissimo, ma il problema non è questo.
    Cercherò di essere più chiaro con un esempio:

    -il browser (ho utilizzato firefox 1.5) vuole ottenere la pagina prova.html, perciò si connette al mio proxy, gli invia una GET prova.html HTTP/1.0, il mio proxy la riceve,apre una connessione al server web e propaga a quest'ultimo la get.

    -il server invia la response al proxy che la propaga al browser.

    -il browser riceve il codice html, lo parsa e individua come hai detto tutti i tag che hanno bisogno di ulteriori connessioni, e per ognuno di essi effettua una nuova connessione al proxy (automaticamente quindi), come prima il proxy propaga la nuova get al server web, e a questo punto se la risorsa indicata nella get è diversa da testo o html la risposta inviata dal server arriva in maniera errata.

    nel mio predcedente messaggio la richiesta

    GET http://localhost/wsdl_files/w3c_home.png HTTP/1.0
    Host: localhost
    User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050715 Firefox/1.0.6 SUSE/1.0.6-16
    Accept: image/png,*/*;q=0.5
    Accept-Language: it,it-it;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: close
    Proxy-Connection: close
    Referer: http://localhost/wsdl.htm

    e la risposta

    HTTP/1.1 200 OK
    Date: Wed, 06 Sep 2006 13:39:43 GMT
    Server: Apache/1.3.37 (Unix)
    Last-Modified: Sat, 02 Sep 2006 18:00:13 GMT
    ETag: "20ab2-790-44f9c6ad"
    Accept-Ranges: bytes
    Content-Length: 1936
    Connection: close
    Content-Type: image/png

    PNG
    â–’


    sono relative al trasferimento di una immagine contenuta nei tag della pagina.
    Come si vede nella risposta anzicheè traferire tutto il dato il mio proxy riceve oltre agli header (prime 9 righe) solo


    PNG
    â–’

    che penso siano solo i primi 8 byte del file png .
    in poche parole il problema sta nel fatto che il mio proxy non riesce a ricevere file diversi da html o testo.
    Spero di non essere stato logorroico e incomprensibile!
    VVoVe:

    grazie per il tuo tempo

  5. #5
    Parla da ignorante in C e rispondo giusto perchè nessuno ti sta ancora dando una mano: ho cercato di intuire il tuo codice e a livello logico mi pare sia tutto corretto a parte qui:
    codice:
    FullWrite(sockfd,request,strlen(request));
    FullRead(sockfd,response,39999999);
    Lato server TCP spedisce il file sotto forma di segmenti spezzettati. Ogni segmento lo ricevi tramite la recv() del socket. Tu non puoi mai sapere quanti bytes ritorna la recv() del socket, può ritornare 1024 come 10. Non è che il risultato è incompleto proprio per questo?
    Che questo sia vero o no credo sia cmq più corretto utilizzare un approccio differente tramite un ciclo while: ogni ciclo while lanci una recv(), prendi i dati dalla recv(), li inserisci in un buffer e da quello li riversi in un file. Quando la socket ritorna 0 o solleva un'eccezione (non so come si comporti C in proposito) interrompi il ciclo while, distruggi il socket, chiudi il file.
    Rilasciata Python FTP Server library 0.5.1
    http://code.google.com/p/pyftpdlib/

    We'll be those who'll make the italian folks know how difficult can be defecating in Southern California without having the crap flying all around the house.

  6. #6
    Billiejoex ha perfettamente ragione però c'è un problema...se la richiesta contiene connection:keep-alive il socket non viene chiuso e quindi il while non uscirebbe dalla recv fino alla successiva richiesta che non è detto che ci sia subito.
    Ci vorrebbe quindi un timeout sulla recv (con una select) ma il valore del timeout potrebbe essere critico da decidere.
    Il modo più sicuro è leggere l'header HTTP, vedere il valore del content-length e quindi leggere i dati con la lunghezza indicata (con l'accortezza di vedere se il browser è IE nel qual caso al valore del content-length va aggiunto 1 perchè la chiavica di IE ci mette un byte più di quello che dice).
    L'header lo sai che è finito perchè c'è un doppio CR-LF; quando leggi il doppio CR-LF interpreti l'header e i bytes che hai letto oltre il CR-LF li considerei come parte iniziale del body e quindi li sottrai dal content-length.

    Buon lavoro

  7. #7
    Moderatore di Sicurezza informatica e virus L'avatar di Habanero
    Registrato dal
    Jun 2001
    Messaggi
    9,782
    scusa ma in base a cosa ritieni di non ricevere tutti i dati dell'immagine??

    Ti faccio notare che nel caso dell'immagine stai ricevendo dati binari e non ascii... e che i dati binari possono anche contenere lo \0... e in C il null è il terminatore di stringa....
    Se stampi una stringa binaria contenende zeri con printf la stampa si blocca non appena trovi un null....
    Leggi il REGOLAMENTO!

    E' molto complicato, un mucchio di input e output, una quantità di informazioni, un mucchio di elementi da considerare, ho una quantità di elementi da tener presente...
    Drugo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.