PDA

View Full Version : [c] programma download http


mamo139
08-01-2009, 14:39
questo codice prima richiede una pagina dal mio sito, poi prova a scaricare un filmato di megavideo... altervista mi risponde perfettamente, mentre megavideo non si fa sentire dopo che mando il mio GET lui non risponde, sta muto ... sto impazzendo... :muro:

grazie mille per l'aiuto:(


#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#include <string.h>
bool scarica(char *fileremoto,char *filelocale,char *host,char modalita);

int main(int argc, char *argv[]){

scarica("/forum2/","a.txt","www.mamo139.altervista.org",'1');
scarica("/files/4ce85b10a5de4f47ea02d653021d0b42/","a.txt","www785.megavideo.com",'1');

getchar();

}

bool scarica(char *fileremoto,char *filelocale,char *host,char modalita){
FILE *fo;
struct sockaddr_in sock; //la struttura per il socket
struct hostent ip; //la struttura per l'indirizzo
bool header = true;
bool invio = false;
char ultimo_carattere = '\0';

char msg_response[] = "\0";
char modo[4];
int s;

//messaggio per il server...
char msg_enter[600] = "GET ";
char protocollo[] = " HTTP/1.1\n";
char protocollo2[] = "Host: ";
char protocollo3[] = "\n";

char dettagli1[] = "Keep-Alive: 300\n";
char dettagli2[] = "Connection: keep-alive";

strcat(msg_enter,fileremoto);
strcat(msg_enter,protocollo);
strcat(msg_enter,protocollo2);
strcat(msg_enter,host);
strcat(msg_enter,protocollo3);

//strcat(msg_enter,dettagli1); //header
//strcat(msg_enter,dettagli2);

strcat(msg_enter,"\n\n");

strcpy(modo,(modalita == '1' ? "w+b" : "w"));
fo=fopen(filelocale,modo); //creazione file

//********* connessione *********//
WORD wVersion;
WSADATA wsaData;
wVersion = MAKEWORD(2, 2);
WSAStartup(wVersion, &wsaData); //winsock startup
s = socket(AF_INET, SOCK_STREAM, 0);

ip = *(gethostbyname(host)); //indirizzo
memcpy(&sock.sin_addr, ip.h_addr, ip.h_length); //copia l'indirizzo nella struttura socket
sock.sin_family = AF_INET;
sock.sin_port = htons(80); //porta


connect(s, (struct sockaddr *)&sock, sizeof(sock)); //associa al socket s la struttura socket
if (!s) {
printf("Connessione non riuscita!!");
getchar();
return false;
}

printf("Inviato al server:\n\n%s\n", msg_enter);
send(s, msg_enter, strlen(msg_enter) + 1, 0); //invia dati
printf("Download in corso...\n\n");

while(recv(s, msg_response, 1, 0) != 0) {

// se sono finiti gli header stampa nel file
if (!header) fprintf(fo,"%c",msg_response[0]);
else printf("%c",msg_response[0]);

// se l'ultimo carattere è uguale a \r, quello attuale è uguale a \n
// e prima c'era già stato un invio (invio==true), mette header=false
if (ultimo_carattere == 13 && msg_response[0] == 10 && invio==true) header=false;
// ulteriore controllo sugli header
((ultimo_carattere == 13 && msg_response[0] == 10) || (ultimo_carattere==10 && invio))?invio=true:invio=false;
// memorizza l'ultimo carattere
ultimo_carattere = msg_response[0];

//fprintf(fo,"%c",msg_response[0]);
}

printf("File Ricevuto\n");

//operazioni di chiusura!
shutdown(s, 2);
closesocket(s);
WSACleanup();
fclose(fo);
return true;
}

cionci
08-01-2009, 15:02
Probabilmente necessita anche di altri header.
Guarda con WireShark la richiesta che viene inviata dal browser e cerca di duplicarla.

mamo139
08-01-2009, 15:16
Probabilmente necessita anche di altri header.
Guarda con WireShark la richiesta che viene inviata dal browser e cerca di duplicarla.

ho provato ad inviarlo con tutti gli header che invia firefox e niente...
ho provato ad inviare con firefox solo l'header che invio io, cioè Host e funziona!!! :cry:

mamo139
08-01-2009, 18:50
Probabilmente necessita anche di altri header.
Guarda con WireShark la richiesta che viene inviata dal browser e cerca di duplicarla.

grazie al tuo programma ho visto che il mio programma mandava un byte 00 finale in piu rispetto al browser...
ho modificato questa riga da
send(s, msg_enter, strlen(msg_enter) + 1, 0);
a
send(s, msg_enter, strlen(msg_enter), 0);

e ora funziona...

per così poco non andava :doh:

grazie :D

fero86
08-01-2009, 19:29
anziché lavorare coi sockets non facevi prima ad usare Windows Internet (http://msdn.microsoft.com/en-us/library/aa385331.aspx) o WinHTTP (http://msdn.microsoft.com/en-us/library/aa384273(VS.85).aspx)?

mamo139
08-01-2009, 20:06
anziché lavorare coi sockets non facevi prima ad usare Windows Internet (http://msdn.microsoft.com/en-us/library/aa385331.aspx) o WinHTTP (http://msdn.microsoft.com/en-us/library/aa384273(VS.85).aspx)?

non ne ero a conoscenza :p

mamo139
08-01-2009, 20:57
anziché lavorare coi sockets non facevi prima ad usare Windows Internet (http://msdn.microsoft.com/en-us/library/aa385331.aspx) o WinHTTP (http://msdn.microsoft.com/en-us/library/aa384273(VS.85).aspx)?


gia che ci sono lo chiedo: esiste un api che mi permette di prendere una pagina tramite un proxy (ovviamente l'indirizzo del proxy glielo passo io come parametro)?? :)

wisher
08-01-2009, 21:40
gia che ci sono lo chiedo: esiste un api che mi permette di prendere una pagina tramite un proxy (ovviamente l'indirizzo del proxy glielo passo io come parametro)?? :)
In C non so quale libreria fornisca questa funzionalità (di sicuro ci sarà e qualcuno te la segnalerà), usando Java invece è molto semplice. L'utilizzo del C è un vincolo per te?

mamo139
09-01-2009, 00:29
In C non so quale libreria fornisca questa funzionalità (di sicuro ci sarà e qualcuno te la segnalerà), usando Java invece è molto semplice. L'utilizzo del C è un vincolo per te?

eh si... java non lo conosco :cry:

però ho guardato i pacchetti in transito quando imposto un proxy nel browser e non sembra molto complicato... adesso ci provo e vi dico come va.
grazie comunque :)

gugoXX
09-01-2009, 10:21
Potrebbe essere una buona occasione per studiare un nuovo linguaggio "moderno".
Come C#, Java o Python.

p.es. In C# tutto quello che hai scritto si riduce a 2 righe di codice.
E con il proxy 3.


class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
//wc.Proxy = new WebProxy(....);
wc.DownloadFile(@"http://www.hwupgrade.it/forum/showthread.php?p=25760450#post25760450", @"c:/QuestoThread.txt");
}
}

mamo139
09-01-2009, 10:33
Potrebbe essere una buona occasione per studiare un nuovo linguaggio "moderno".
Come C#, Java o Python.

p.es. In C# tutto quello che hai scritto si riduce a 2 righe di codice.
E con il proxy 3.


class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
//wc.Proxy = new WebProxy(....);
wc.DownloadFile(@"http://www.hwupgrade.it/forum/showthread.php?p=25760450#post25760450", @"c:/QuestoThread.txt");
}
}


mhhh... tutto troppo bello e facile... :mbe:
non è che ha qualche dipendenza particolare?? tipo librerie??
ad asempio il tuo programma funziona su un windows xp he sp1 basebase con nulla installato o ci vuole qualche pacchetto .NET o robe varie installate??

gugoXX
09-01-2009, 10:48
ovviamente ci vuole il .NET framework installato.
Ma solo quello.

Questo per qualsiasi programma fatto in C# o VB.net (o C++.net), anche solo Hello World.

wisher
09-01-2009, 10:49
Potrebbe essere una buona occasione per studiare un nuovo linguaggio "moderno".
Come C#, Java o Python.

p.es. In C# tutto quello che hai scritto si riduce a 2 righe di codice.
E con il proxy 3.


class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
//wc.Proxy = new WebProxy(....);
wc.DownloadFile(@"http://www.hwupgrade.it/forum/showthread.php?p=25760450#post25760450", @"c:/QuestoThread.txt");
}
}

Anche in Java si fa in modo simile. Per questo lo consigliavo.
mhhh... tutto troppo bello e facile... :mbe:
non è che ha qualche dipendenza particolare?? tipo librerie??
ad asempio il tuo programma funziona su un windows xp he sp1 basebase con nulla installato o ci vuole qualche pacchetto .NET o robe varie installate??
Per poterlo eseguire devi avere installato il framework .Net

mamo139
09-01-2009, 10:53
ovviamente ci vuole il .NET framework installato.
Ma solo quello.

Questo per qualsiasi programma fatto in C# o VB.net (o C++.net), anche solo Hello World.

capito, grazie per le info :)
finche riesco a cavarmela con 20 minuti di smanettamenti continuo così... appena incontro uno scoglio insormontabile proverò a cambiare linguaggio...
però non facendo per lavoro ma solo per hobby alla fine mi diverto quasi a complicarmi la vita :D

banryu79
09-01-2009, 11:01
però non facendo per lavoro ma solo per hobby alla fine mi diverto quasi a complicarmi la vita :D

Ah, ecco, mi sembrava :asd:
Allora buona goduria :)

cionci
09-01-2009, 12:14
mhhh... tutto troppo bello e facile... :mbe:
non è che ha qualche dipendenza particolare?? tipo librerie??
ad asempio il tuo programma funziona su un windows xp he sp1 basebase con nulla installato o ci vuole qualche pacchetto .NET o robe varie installate??
Anche in C con libcurl è molto semplice: http://curl.haxx.se/lxr/source/docs/examples/simple.c

mamo139
09-01-2009, 12:51
dai sempre per rimanere a lavorare con le socket grezze vi chiedo questo:

quando provo a connettermi con:
connect(s, (struct sockaddr *)&sock, sizeof(sock));

come posso impostare un timeout, in modo che se il server non mi risponde il mio programma non sta piantato delle ore ad aspettare?? :p

~FullSyst3m~
09-01-2009, 18:06
Potrebbe essere una buona occasione per studiare un nuovo linguaggio "moderno".
Come C#, Java o Python.

p.es. In C# tutto quello che hai scritto si riduce a 2 righe di codice.
E con il proxy 3.


class Program
{
static void Main(string[] args)
{
WebClient wc = new WebClient();
//wc.Proxy = new WebProxy(....);
wc.DownloadFile(@"http://www.hwupgrade.it/forum/showthread.php?p=25760450#post25760450", @"c:/QuestoThread.txt");
}
}


Python:

import urllib
urllib.urlretrieve("http://www.hwupgrade.it/forum/showthread.php?p=25760450#post25760450", "C:\QuestoThread.txt")

DanieleC88
09-01-2009, 18:43
Abbiamo un nuovo cdimauro tra di noi... :asd:

~FullSyst3m~
09-01-2009, 19:13
Abbiamo un nuovo cdimauro tra di noi... :asd:

:D :D :D
:asd: :asd: :asd:

mamo139
14-01-2009, 16:08
posso introdurre un timeout anche alle recv??
ho pensato che si possa fare così, ma purtroppo sbaglio
mi entra in loop...
come posso fare?
grazie;)



SOCKET sd;
fd_set fds;
struct timeval timeout;
unsigned long cmd;

// definizione strutture .....
// ...

if ((sd=socket(AF_INET,SOCK_STREAM,0))<0)
{ printf("err:sock\n");
exit(-1);
}

// imposto socket non boccante
cmd=1;
ioctlsocket( sd, FIONBIO, &cmd);

// dati per Select
timeout.tv_sec = 3; // numero di secondi per il timeout
timeout.tv_usec = 0; // numero di microsecondi per il timeout
FD_ZERO(&fds);
FD_SET(sd, &fds); // aggiungo sd all'elenco dei socket gestiti da select

// ritorna sempre l'errore WSAEWOULDBLOCK!!
connect(sd,(struct sockaddr *)&rem_ind,sizeof(struct sockaddr_in));

if (select(sd+1, 0, &fds, 0, &timeout)>0) //il primo argomento di select è ignorato sotto windows
{
printf("# connesso\n");


//**************************** MIA MODIFICA **************
recv(s, msg_response, 1, 0);
if(select(sd+1, 0, &fds, 0, &timeout)>0){
printf("# ricevuto un byte!\n");
else
printf("# timeout!\n");


}
else printf("# timeout!\n");