Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Войти
 
Страницы: 1
RSS
Скачивание файла по http на winsock
 
Здравствуйте!
Может кто сталкивался со следующей проблемой:
Нужно скачать файл с Web-сервера используя winsoock. С реализацией всё вроде понятно, заносим в массив параметры HTTP протокола. Отправляем на сервер, и ждём получения ответа. Затем парсим тело ответа на наличие файла, заносим его в массив, и пытаемся записать в файл. Вроде в ответе содержиться массив действующего файла, а записывается какая-то чушь. Как записать правильно файл?

Код
 int file_download(void) // ф-ия скачки файла
{
   char sendbuffer[1024], recvbuffer[65535];

        strcpy(sendbuffer, "GET ");
        strcat(sendbuffer, "http://test1.ru/1.gif");
        strcat(sendbuffer, " HTTP/1.0\r\nHost: ");
        strcat(sendbuffer, "test1.ru");
        strcat(sendbuffer, "\r\n\r\n");

        memset(recvbuffer,0,sizeof(recvbuffer)-1);
         MessageBox(0,sendbuffer,"Send Buffer",0);

    SOCKET s = socket(AF_INET,SOCK_STREAM,0);
    SOCKADDR_IN webaddr;
        webaddr.sin_addr.S_un.S_addr = resolve("test1.ru");
        webaddr.sin_family = AF_INET;
        webaddr.sin_port = htons(80);
    if(connect(s, (struct sockaddr *)&webaddr,sizeof(SOCKADDR_IN))) return -1;

    send(s, sendbuffer, strlen(sendbuffer),0);
    Sleep(2000);

    int i;
    while(i = recv(s,recvbuffer+strlen(recvbuffer),1,0))  // получаем ответ
    {if (i == SOCKET_ERROR) return -1;}
         MessageBox(0,recvbuffer,"Answer of Web Server",0);

      // parsing...
    char *temp;

    for(int i = 0; recvbuffer[i]!=0; ++i)
    {
        if((recvbuffer[i]=='\r')&&(recvbuffer[i+1]=='\n')&&
            (recvbuffer[i+2]=='\r')&&(recvbuffer[i+3]=='\n'))
        {temp = (char*)&recvbuffer[i]+4; break;}
    }
        MessageBox(0,temp,"Answer of Web Server",0);

        FILE *stream= fopen("1.gif", "wb");
          //fprintf(stream, temp);
          fwrite(&temp, sizaof(temp), 1, stream);
          fclose(stream);

     return 0;
}
Изменено: flintstone - 20.12.2008 09:45:26
 
Зацени  ;)
Код
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <strings.h> 

SOCKET HTTPConnectToServer(char* server){
       SOCKADDR_IN serverInfo;
       SOCKET sck; 
       WSADATA wsaData; 
       LPHOSTENT hostEntry; 
       WSAStartup(MAKEWORD(2,2),&wsaData);
       hostEntry = gethostbyname(server);
       if(!hostEntry){  
             WSACleanup();  
             return 0; 
       } 
       sck = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
       if(sck==INVALID_SOCKET){
             WSACleanup(); 
             puts("Failed to setup socket");
             getchar(); 
             return 0; 
       } 
       serverInfo.sin_family = AF_INET;
       serverInfo.sin_addr   = *((LPIN_ADDR)*hostEntry->h_addr_list); 
       serverInfo.sin_port   = htons(80); 
       int i = connect(sck,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
     
       if(sck==SOCKET_ERROR) return 0;
       if(i!=0) return 0;
     
       return sck;
}

void HTTPRequestPage(SOCKET s,char *page,char *host){
     unsigned int len;
     if(strlen(page)>strlen(host)){
        len=strlen(page);
     }else len = strlen(host);
     
     char message[20+len];
     if(strlen(page)<=0){
        strcpy(message,"GET / HTTP/1.1\r\n");
     }else sprintf(message,"GET %s HTTP/1.1\r\n",page);
     send(s,message,strlen(message),0);
     
     memset(message,0,sizeof(message));
     sprintf(message,"Host: %s\r\n\r\n",host);
     send(s,message,strlen(message),0);
}

BOOL DownloadToBuffer(char * webpage,char * buffer,unsigned long max){
     if(webpage==NULL||buffer==NULL||max==0) return FALSE;
     
     unsigned short shift=0;
     if(strncasecmp(webpage,"http://",strlen("http://"))==0){
          shift=strlen("http://");
     }
     if(strncasecmp(webpage+shift,"www.",strlen("www."))==0){
          shift+=strlen("www.");
     }
     char cut[strlen(webpage)-shift+1];
     strcpy(cut,strdup(webpage+shift));
     
     char *server = strtok(cut,"/");
     
     char *page = strdup(webpage+shift+strlen(server));
     
     SOCKET s = HTTPConnectToServer(server);
     HTTPRequestPage(s,page,server);
     
     int i = recv(s,buffer,max,0);
     closesocket(s);
     
     if(i<=0) return FALSE;
     return TRUE;
}

int main(int argc,char *argv[]){
    char buffer[2000];
    memset(buffer,0,sizeof(buffer));
    DownloadToBuffer("http://www.IsItThursday.com/",buffer,sizeof(buffer));
    
    printf(buffer);
    
    getchar();
    return 0;
}

P.S.: Приделать CreateFile + WriteFile думаю не составит труда... Ну а если не обязательно WinSock API юзай WinInet API... URLDownloadToFile  ;)
Код
#pragma comment(lib, "urlmon.lib")
#include <windows.h>
#include <urlmon.h>
#include <stdio.h>
#include <string.h>

LPSTR DownloadURLToBuffer(LPCSTR lpszURL)
{
    LPSTR lpResult = NULL;
    LPSTREAM lpStream;
    if(lpszURL && SUCCEEDED(URLOpenBlockingStream(NULL, lpszURL, &lpStream, 0, NULL))){
        STATSTG statStream;
        if(SUCCEEDED(lpStream->Stat(&statStream, STATFLAG_NONAME))){
            DWORD dwSize = statStream.cbSize.LowPart + 1;
            lpResult = (LPSTR)malloc(dwSize);
            if(lpResult){
                LARGE_INTEGER liPos;
                ZeroMemory(&liPos, sizeof(liPos));
                ZeroMemory(lpResult, dwSize);
                lpStream->Seek(liPos, STREAM_SEEK_SET, NULL);
                lpStream->Read(lpResult, dwSize - 1, NULL);
            }
        }
        lpStream->Release();
    }
    return lpResult;
}

int main(int argc, char *argv[])
{
    if(SUCCEEDED(CoInitialize(NULL))){
        LPSTR lpszData = DownloadURLToBuffer("http://www.IsItThursday.com/");
        printf("%s\n", lpszData);
        free(lpszData);
        CoUninitialize();
    }
    return 0;
}
 
:!: Ах да и не забудь либы поключить вручную либо через #pragma comment!!!
 
Твой код тоже рабочий, правда так записать файл и не удаются. Вот переделал под CreateFile + WriteFile, например для рисунка 1.gif размером 179 байт:

Код
int file_download(void) // ф-ия скачки файла
{
char sendbuffer[1024], recvbuffer[65535];

strcpy(sendbuffer, "GET ");
strcat(sendbuffer, "http://test1.ru/1.gif");
strcat(sendbuffer, " HTTP/1.0\r\nHost: ");
strcat(sendbuffer, "test1.ru");
strcat(sendbuffer, "\r\n\r\n");

memset(recvbuffer,0,sizeof(recvbuffer)-1);
MessageBox(0,sendbuffer,"Send Buffer",0);

SOCKET s = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN webaddr;
webaddr.sin_addr.S_un.S_addr = resolve("test1.ru");
webaddr.sin_family = AF_INET;
webaddr.sin_port = htons(80);
if(connect(s, (struct sockaddr *)&webaddr,sizeof(SOCKADDR_IN))) return -1;

send(s, sendbuffer, strlen(sendbuffer),0);
Sleep(2000);

int i;
while(i = recv(s,recvbuffer+strlen(recvbuffer),1,0)) // получаем ответ
{if (i == SOCKET_ERROR) return -1;}
MessageBox(0,recvbuffer,"Answer of Web Server",0);

// parsing...
char *temp;

for(int i = 0; recvbuffer[i]!=0; ++i)
{
if((recvbuffer[i]=='\r')&&(recvbuffer[i+1]=='\n')&&
(recvbuffer[i+2]=='\r')&&(recvbuffer[i+3]=='\n'))
{temp = (char*)&recvbuffer[i]+4; break;}
}
MessageBox(0,temp,"Answer of Web Server",0);

    HANDLE hTempFile = CreateFile("11.gif",  
        GENERIC_READ | GENERIC_WRITE, 
        0,                            
        NULL,                         
        CREATE_ALWAYS,               
        FILE_ATTRIBUTE_NORMAL,        
        NULL);                        

    if (hTempFile == INVALID_HANDLE_VALUE)
    {
        printf("Could not create destination file.");
        return 0;
    }

    DWORD  dwBytesWritten;

    WriteFile(hTempFile, temp, 179,
    &dwBytesWritten, NULL);

    CloseHandle(hTempFile);

return 0;
}


Если сравнить по шестнадцатиричному значению, то видно существенные отличия:
Искомый файл:


То что записали:


Откуда они вдруг появились? Хотя при приёме данных в массив с помощью recv, он идентичен искомому файлу.
Изменено: flintstone - 20.12.2008 01:30:13
 
Вообщем, не могу сказать что нашёл у себя ошибку, но кому интересно, то можно посмотреть пример http://www.codeproject.com/KB/IP/winsockintro02.aspx
Страницы: 1
Читают тему