Pobieranie plików przez HTTP/1.0- kod w C.
Funkcja na pobranie plików (w tym binarnych np. jpg), zastępująca zawodne i
skomplikowane UrlDownloadToFile:
/* start kodu */
#include <stdio.h> /* biblioteka stdio */
#include <winsock.h> /* biblioteka winsock */
#define BSIZE 1024 /* wielkosc bufora */
#ifndef __cplusplus /* drobne poprawki dla C */
#define bool int
#define true 1
#define false 0
#endif
bool DirectoryExists ( char szDirectory [ ] )
{
int iCode = GetFileAttributes ( szDirectory );
return ( iCode != - 1 ) && ( FILE_ATTRIBUTE_DIRECTORY & iCode );
}
/*
użycie:
Download ( "onet.pl", "C:\\onet.pl.txt" ); //odsyła do
http://www.onet.pl/
Download ( "onet.pl/", "C:\\onet.pl_.txt" ); //odsyła do
http://www.onet.pl/
Download ( "www.onet.pl",
"C:\\www.onet.pl.txt"
); //działa
Download ( "www.onet.pl/",
"C:\\www.onet.pl_.txt"
); //działa
Download (
"http://onet.pl", "C:\\http___onet.pl.txt" ); //odsyła do
http://www.onet.pl/
Download (
"http://onet.pl/", "C:\\http___onet.pl_.txt" ); //odsyła do
http://www.onet.pl/
Download (
"http://www.onet.pl", "C:\\http___www.onet.pl.txt" ); //działa
Download (
"http://www.onet.pl/", "C:\\http___www.onet.pl_.txt" ); //działa
Download (
"http://myhome.elim.net/taekwondo/wtf/img/manimg5.gif", "C:\\wtf.gif" );
//działa
*/
int Download ( char szUrl [ ], char szLocalFile [ ] )
{
int iSocket;
int iBytes;
int iTmp = 0;
bool bWrite = false;
char szByte [ 1 ];
WORD wVersionRequested = MAKEWORD ( 1, 1 );
WSADATA WSAData;
struct in_addr hAddr;
struct sockaddr_in Server;
struct hostent * Host;
char szTxtToSend [ BSIZE ] = "";
char szFile [ BSIZE ] = "";
char szHost [ BSIZE ] = "";
char szTmp [ BSIZE ];
char * pChar;
FILE * pFile;
pChar = strchr ( szLocalFile, '\\' );
while ( pChar != 0 )
{
strcpy ( szTmp, szLocalFile );
szTmp [ pChar - szLocalFile ] = '\0';
if ( ! DirectoryExists ( szTmp ) )
CreateDirectory ( szTmp, 0 );
pChar = strchr ( pChar + 1, '\\' );
}
strcpy ( szHost, szUrl );
if ( strncmp ( szHost,
"http://", 7 ) == 0 )
{
iTmp += 7;
strcpy ( szHost, szHost + 7 );
}
if ( strchr ( szHost, '/' ) )
szHost [ strchr ( szHost, '/' ) - szHost ] = '\0';
iTmp += strlen ( szHost );
strcpy ( szFile, szUrl + iTmp );
if ( strcmp ( szFile, "" ) == 0 )
strcpy ( szFile, "/" );
sprintf ( szTxtToSend, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", szFile, szHost
);
if ( WSAStartup ( wVersionRequested, & WSAData ) ) return 0;
if ( ( iSocket = socket ( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) return
0;
if ( ! ( Host = gethostbyname ( ( char * ) szHost ) ) ) return 0;
if ( ! ( pFile = fopen ( szLocalFile, "wb" ) ) ) return 0;
hAddr . s_addr = * ( ( unsigned long * ) Host -> h_addr_list [ 0 ] );
memset ( & Server, 0, sizeof ( Server ) );
Server . sin_family = AF_INET;
Server . sin_addr . s_addr = inet_addr ( inet_ntoa ( hAddr ) );
Server . sin_port = htons ( 80 );
if ( connect ( iSocket, ( struct sockaddr * ) & Server, sizeof ( Server ) ) <
0 ) return 0;
send ( iSocket, szTxtToSend, strlen ( szTxtToSend ), 0 );
iTmp = 0;
while ( true )
{
memset ( szByte, '\0', sizeof ( szByte ) );
iBytes = recv ( iSocket, szByte, 1, 0 );
if ( ! iBytes ) break;
if ( bWrite )
fputc ( szByte [ 0 ], pFile );
if ( szByte [ 0 ] == '\r' ) iTmp ++;
else if ( szByte [ 0 ] == '\n' ) iTmp ++;
else iTmp = 0;
if ( ! bWrite && iTmp == 4 )
bWrite = true;
}
fclose ( pFile );
closesocket ( iSocket );
WSACleanup ( );
return 1;
}
/* koniec kodu */
W wypadku błędów trzeba dołączyć bibliotekę libwsock32.lib.
Opracował: rainrider