Cooker
November 30th, 2007, 10:00 PM
Hi,
I write a program to download files from HTTP server. Such as:
Download.exe http://www.codeproject.com/info/stuff/codeproject_w2k_bg.gif
Download.exe http://us.i1.yimg.com/us.yimg.com/i/us/nt/ma/ma_ga_1.gif
But if I try download files from [http://www.boilsoft.com/download.html], such as
Download.exe http://www.boilsoft.net/download/boilsoft_mp4_converter.exe
I find the downloaded file is smaller than the original file and check the content:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL /download/boilsoft_mp4_converter.exe was not found on this server.<P>
<P>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.
<HR>
<ADDRESS>Apache/1.3.33 Server at cpanel.ev1servers.net Port 80</ADDRESS>
</BODY></HTML>
The server tells me "download/boilsoft_mp4_converter.exe was not found on this server". But by IE browser, I enter that web site, right-click the link and download the file. Downloading is completed and successful.
Another problem is sometimes"files aren't completely downloaded", the downloaded files are smaller than original files. This time, the specific file can downloaded completely, but the another time, the same file can't download completely. Why shall I solve?
The following is the code
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h> // for Winsock
#pragma comment(lib,"Ws2_32.lib") // for Winsock
#define DEFAULT_BUFLEN 512
int ParseURL(char *url, char servername[], char filepath[], char filename[]);
void ErrExit(const char *format, ...);
int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
int err = 0;
int recvbytes = 0;
int sentbytes = 0;
SOCKET sockfd = 0;
struct sockaddr_in dest ;
struct hostent *remote_host = 0;
char *url = argv[1];
char servername[128], filepath[128], filename[128];
char sendbuf[128];
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int headerlength = 0;
char *division;
FILE *fp;
if (argc != 2) {
printf("usage: Download file_url\n");
return -1;
}
// Parse the URL
if (ParseURL(url, servername, filepath, filename) == -1) {
printf("Incorrect file url(%s)\n", argv[1]);
return -1;
}
// Initiate use of the Winsock DLL
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
// Could not find a usable WinSock DLL
printf("Couldn't find a usable WinSock DLL.\n");
return -1;
}
// Confirm that the WinSock DLL supports 2.2.
// Note that if the DLL supports versions greater than 2.2
// in addition to 2.2, it will still return 2.2 in wVersion
// since that is the version we requested.
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)
ErrExit("Bad winsock version.\n");
// Create a socket that is bound to a specific transport service provider
// AF_INET : The Internet Protocol version 4 (IPv4) address family
// SOCK_STREAM: Use the TCP for the Internet address family
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == INVALID_SOCKET)
ErrExit("Can't open a socket with error code %d\n", WSAGetLastError());
// Initialize the server address/port struct
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if (isalpha(servername[0])) {
if ((remote_host = gethostbyname(servername)) == NULL) {
closesocket(sockfd);
ErrExit("Can't get \"%s\" host entry\n", servername);
} else {
dest.sin_addr.s_addr = *((u_long *)(remote_host->h_addr_list[0]));
}
} else {
if ((dest.sin_addr.s_addr = inet_addr(servername)) == INADDR_NONE) {
closesocket(sockfd);
ErrExit("Can't get \"%s\" host entry\n", servername);
}
}
dest.sin_family = AF_INET;
dest.sin_port = htons(80);
memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
// Establish a connection to a specified socket
err = connect(sockfd, (struct sockaddr *)&dest, sizeof(dest));
if (err == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("connect() failed with error: %d\n", WSAGetLastError());
}
// Open a file that stores the data received from server
fp = fopen(filename, "wb");
if (fp == NULL) {
closesocket(sockfd);
ErrExit("Can't open a file.\n");
}
// Send our GET request for http
// Request: GET file_path HTTP/1.1
memset(sendbuf, 0 ,sizeof(sendbuf));
sprintf(sendbuf, "GET %s\r\n\r\nHTTP/1.1", filepath);
sentbytes = send(sockfd, sendbuf, sizeof(sendbuf), 0);
if (sentbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("send() failed with error: %d\n", WSAGetLastError());
}
// Receive the HTTP response: HTTP headers + entity body
// The division between the headers and the entity body is
// designated by two carriage returns/line feeds.
recvbytes = recv(sockfd, recvbuf, recvbuflen, 0);
if (recvbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("recv() failed with error: %d\n", WSAGetLastError());
}
// Skip the HTTP headers, and just store entity body
division = strstr(recvbuf, "\n\n");
if (division != NULL) {
headerlength = division - recvbuf + 2;
fwrite(recvbuf + headerlength, 1, recvbytes - headerlength, fp);
} else { // no HTTP headers
fwrite(recvbuf, 1, recvbytes, fp);
}
do {
recvbytes = recv(sockfd, recvbuf, recvbuflen, 0);
if (recvbytes >0) {
fwrite(recvbuf, 1, recvbytes, fp);
} else if (recvbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("recv() failed with error: %d\n", WSAGetLastError());
}
} while(recvbytes > 0);
fclose(fp);
printf("File downloaded and saved as %s\n",filename);
// Close the socket and terminate use of the Winsock 2 DLL (Ws2_32.dll)
closesocket(sockfd);
WSACleanup();
system("pause");
return 0;
}
// ========================================================
// Parse the URL into server name, file path, and file name
========================================================
int ParseURL(char *url, char servername[], char filepath[], char filename[])
{
char *pch;
char *tmp_url = url;
unsigned short int url_length = strlen(url);
unsigned short int server_name_length = 0;
if (strncmp(tmp_url, "http://", 7) != 0)
return -1;
else
{
pch = strchr(tmp_url + 7, '/');
if (pch == 0)
return -1;
server_name_length = pch - tmp_url -7;
strncpy(servername, url + 7, server_name_length);
servername[server_name_length] = '\0';
}
strncpy(filepath, pch, url_length - server_name_length - 7);
filepath[url_length - server_name_length - 7] = '\0';
pch = strrchr(pch, '/');
strcpy(filename, pch + 1);
return 0;
}
void ErrExit(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
WSACleanup();
exit(1);
}
I write a program to download files from HTTP server. Such as:
Download.exe http://www.codeproject.com/info/stuff/codeproject_w2k_bg.gif
Download.exe http://us.i1.yimg.com/us.yimg.com/i/us/nt/ma/ma_ga_1.gif
But if I try download files from [http://www.boilsoft.com/download.html], such as
Download.exe http://www.boilsoft.net/download/boilsoft_mp4_converter.exe
I find the downloaded file is smaller than the original file and check the content:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL /download/boilsoft_mp4_converter.exe was not found on this server.<P>
<P>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.
<HR>
<ADDRESS>Apache/1.3.33 Server at cpanel.ev1servers.net Port 80</ADDRESS>
</BODY></HTML>
The server tells me "download/boilsoft_mp4_converter.exe was not found on this server". But by IE browser, I enter that web site, right-click the link and download the file. Downloading is completed and successful.
Another problem is sometimes"files aren't completely downloaded", the downloaded files are smaller than original files. This time, the specific file can downloaded completely, but the another time, the same file can't download completely. Why shall I solve?
The following is the code
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h> // for Winsock
#pragma comment(lib,"Ws2_32.lib") // for Winsock
#define DEFAULT_BUFLEN 512
int ParseURL(char *url, char servername[], char filepath[], char filename[]);
void ErrExit(const char *format, ...);
int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
int err = 0;
int recvbytes = 0;
int sentbytes = 0;
SOCKET sockfd = 0;
struct sockaddr_in dest ;
struct hostent *remote_host = 0;
char *url = argv[1];
char servername[128], filepath[128], filename[128];
char sendbuf[128];
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int headerlength = 0;
char *division;
FILE *fp;
if (argc != 2) {
printf("usage: Download file_url\n");
return -1;
}
// Parse the URL
if (ParseURL(url, servername, filepath, filename) == -1) {
printf("Incorrect file url(%s)\n", argv[1]);
return -1;
}
// Initiate use of the Winsock DLL
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
// Could not find a usable WinSock DLL
printf("Couldn't find a usable WinSock DLL.\n");
return -1;
}
// Confirm that the WinSock DLL supports 2.2.
// Note that if the DLL supports versions greater than 2.2
// in addition to 2.2, it will still return 2.2 in wVersion
// since that is the version we requested.
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2)
ErrExit("Bad winsock version.\n");
// Create a socket that is bound to a specific transport service provider
// AF_INET : The Internet Protocol version 4 (IPv4) address family
// SOCK_STREAM: Use the TCP for the Internet address family
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == INVALID_SOCKET)
ErrExit("Can't open a socket with error code %d\n", WSAGetLastError());
// Initialize the server address/port struct
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if (isalpha(servername[0])) {
if ((remote_host = gethostbyname(servername)) == NULL) {
closesocket(sockfd);
ErrExit("Can't get \"%s\" host entry\n", servername);
} else {
dest.sin_addr.s_addr = *((u_long *)(remote_host->h_addr_list[0]));
}
} else {
if ((dest.sin_addr.s_addr = inet_addr(servername)) == INADDR_NONE) {
closesocket(sockfd);
ErrExit("Can't get \"%s\" host entry\n", servername);
}
}
dest.sin_family = AF_INET;
dest.sin_port = htons(80);
memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
// Establish a connection to a specified socket
err = connect(sockfd, (struct sockaddr *)&dest, sizeof(dest));
if (err == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("connect() failed with error: %d\n", WSAGetLastError());
}
// Open a file that stores the data received from server
fp = fopen(filename, "wb");
if (fp == NULL) {
closesocket(sockfd);
ErrExit("Can't open a file.\n");
}
// Send our GET request for http
// Request: GET file_path HTTP/1.1
memset(sendbuf, 0 ,sizeof(sendbuf));
sprintf(sendbuf, "GET %s\r\n\r\nHTTP/1.1", filepath);
sentbytes = send(sockfd, sendbuf, sizeof(sendbuf), 0);
if (sentbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("send() failed with error: %d\n", WSAGetLastError());
}
// Receive the HTTP response: HTTP headers + entity body
// The division between the headers and the entity body is
// designated by two carriage returns/line feeds.
recvbytes = recv(sockfd, recvbuf, recvbuflen, 0);
if (recvbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("recv() failed with error: %d\n", WSAGetLastError());
}
// Skip the HTTP headers, and just store entity body
division = strstr(recvbuf, "\n\n");
if (division != NULL) {
headerlength = division - recvbuf + 2;
fwrite(recvbuf + headerlength, 1, recvbytes - headerlength, fp);
} else { // no HTTP headers
fwrite(recvbuf, 1, recvbytes, fp);
}
do {
recvbytes = recv(sockfd, recvbuf, recvbuflen, 0);
if (recvbytes >0) {
fwrite(recvbuf, 1, recvbytes, fp);
} else if (recvbytes == SOCKET_ERROR) {
closesocket(sockfd);
ErrExit("recv() failed with error: %d\n", WSAGetLastError());
}
} while(recvbytes > 0);
fclose(fp);
printf("File downloaded and saved as %s\n",filename);
// Close the socket and terminate use of the Winsock 2 DLL (Ws2_32.dll)
closesocket(sockfd);
WSACleanup();
system("pause");
return 0;
}
// ========================================================
// Parse the URL into server name, file path, and file name
========================================================
int ParseURL(char *url, char servername[], char filepath[], char filename[])
{
char *pch;
char *tmp_url = url;
unsigned short int url_length = strlen(url);
unsigned short int server_name_length = 0;
if (strncmp(tmp_url, "http://", 7) != 0)
return -1;
else
{
pch = strchr(tmp_url + 7, '/');
if (pch == 0)
return -1;
server_name_length = pch - tmp_url -7;
strncpy(servername, url + 7, server_name_length);
servername[server_name_length] = '\0';
}
strncpy(filepath, pch, url_length - server_name_length - 7);
filepath[url_length - server_name_length - 7] = '\0';
pch = strrchr(pch, '/');
strcpy(filename, pch + 1);
return 0;
}
void ErrExit(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
WSACleanup();
exit(1);
}