Скачать файл с интернета по прямой ссылке - C (СИ)
Формулировка задачи:
появилась необходимость в скачивании файла с инета по прямой ссылке, но к сажелению в инете на СИ ненашел,очень надеюсь на вашу помощь. (например скачать test.txt файл с mysite.ru/test.txt)
Решение задачи: «Скачать файл с интернета по прямой ссылке»
textual
Листинг программы
// by SlyBit (c) 07.2008 /DownloadFile.cpp/ #include "winsock2.h" #include <windows.h> #pragma comment(lib, "Ws2_32.lib") #pragma comment(linker, "/ENTRY:Main") #define HOST_NAME "wasm.ru" #define URL_NAME "/pub/21/files/lockfileswork/RawRead.rar" #define FILE_NAME "RawRead.rar" #define HEADER_SIZE 400 // Возводим число x в положительную целочисленную степень #define DEGREE(Val, Deg) if(!Deg) { Val = 1; } else for(int i1=2, i2=Val; i1<=Deg; i1++) { Val *= i2; } // Переводим число Str, представленное в виде строки в числовой вид Int #define STR_TO_INT(Str, Int) for(int l=0, s=10; l<strlen(Str); l++, s=10) { DEGREE(s, (strlen(Str)-1-l)); Int += ((BYTE)Str[l]-0x30)*s; } PCHAR WINAPI HTTPSendReceiveData(PVOID pInData, DWORD dwInDataSize, PCHAR pIpAddress, PDWORD pOutSizeSize) { SOCKET ConnectSocket; sockaddr_in ClientService; INT nReceiveBytes, i, j = 0, nCurr; CHAR szHeader[HEADER_SIZE] = "\0", szVal[10] = "\0"; PCHAR pOutData = 0; if(INVALID_SOCKET == (ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))) { return 0; } ClientService.sin_family = AF_INET; ClientService.sin_port = htons(80); ClientService.sin_addr.s_addr = inet_addr(pIpAddress); if(SOCKET_ERROR == connect(ConnectSocket, (SOCKADDR*)&ClientService, sizeof(ClientService))) { closesocket(ConnectSocket); return 0; } if(SOCKET_ERROR == send(ConnectSocket, (PCHAR)pInData, dwInDataSize, 0)) { closesocket(ConnectSocket); return 0; } // Получаем заголовок ответа if(SOCKET_ERROR == recv(ConnectSocket, szHeader, HEADER_SIZE, 0)) { closesocket(ConnectSocket); return 0; } for(i=0; i<HEADER_SIZE; i++) { // Получаем размер данных if(!memcmp("Content-Length: ", szHeader+i, strlen("Content-Length: ")-1)) { do { szVal[j] = szHeader[i+strlen("Content-Length: ")+j]; j++; } while(szHeader[i+strlen("Content-Length: ")+j] != '\r'); STR_TO_INT(szVal, *pOutSizeSize); } // Получаем указатель на начало файла в ответе if(!memcmp("\r\n\r\n", szHeader+i, strlen("\r\n\r\n")-1)) { i += strlen("\r\n\r\n"); break; } } if((HEADER_SIZE-1 == i) || !*pOutSizeSize) { return 0; } if(!(pOutData = (PCHAR)VirtualAlloc(0, *pOutSizeSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) { return 0; } if(HEADER_SIZE-i >= *pOutSizeSize) { memcpy(pOutData, szHeader+i, *pOutSizeSize); } else { nCurr = HEADER_SIZE-i; memcpy(pOutData, szHeader+i, nCurr); // Получаем оставшиеся данные while(nReceiveBytes = recv(ConnectSocket, pOutData+nCurr, *pOutSizeSize-nCurr, 0)) { if(nReceiveBytes == SOCKET_ERROR) { closesocket(ConnectSocket); return 0; } nCurr += nReceiveBytes; } } closesocket(ConnectSocket); return pOutData; } BOOL WINAPI GetIpByHostName(PCHAR pHostName, PCHAR pIp, DWORD dwIpSize) { hostent *pHosten; if(!(pHosten = gethostbyname(pHostName))) { return 0; } if(lstrlen(inet_ntoa(*(in_addr*)*pHosten->h_addr_list)) > dwIpSize) { return 0; } lstrcpy(pIp, inet_ntoa(*(in_addr*)*pHosten->h_addr_list)); return 1; } BOOL WINAPI DownloadFile(PCHAR pFileName, PCHAR pHostName, PCHAR pUrl) { CHAR szIp[17], szSendData[300]; PCHAR pFile = 0; HANDLE hFile; DWORD dwFileSize = 0, dwRetSize; if(!GetIpByHostName(pHostName, szIp, 17)) { return 0; } wsprintf(szSendData, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", pUrl, pHostName); if(!(pFile = HTTPSendReceiveData(szSendData, strlen(szSendData), szIp, &dwFileSize))) { return 0; } if(INVALID_HANDLE_VALUE == (hFile = CreateFile(pFileName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0))) { VirtualFree(pFile, 0, MEM_RELEASE); return 0; } if(!WriteFile(hFile, pFile, dwFileSize, &dwRetSize, 0)) { VirtualFree(pFile, 0, MEM_RELEASE); CloseHandle(hFile); return 0; } VirtualFree(pFile, 0, MEM_RELEASE); CloseHandle(hFile); return 1; } VOID WINAPI Main() { WSAData wsaData; if(NO_ERROR != WSAStartup(MAKEWORD(2,2), &wsaData)) { ExitProcess(0); } if(DownloadFile(FILE_NAME, HOST_NAME, URL_NAME)) { MessageBox(0, "DownloadFile Ok", 0, 0); } else { MessageBox(0, "DownloadFile Error", 0, 0); } ExitProcess(0); }