Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

File downloader (C++)

AseshAsesh Member Posts: 52
I have written a code to download this file: www.codeproject.com/info/stuff/codeproject_w2k_bg.gif

The command was successfully sent using ::send function and this is what I sent to the server "GET http://www.codeproject.com/info/stuff/codeproject_w2k_bg.gif"

And when I call ::recv (after a successful connection to the server), it will return after about a minute and return 0. Can anyone find a solution for this w/o using WinHTTP?

Comments

  • PruyquePruyque Member Posts: 149
    : I have written a code to download this file: www.codeproject.com/info/stuff/codeproject_w2k_bg.gif
    :
    : The command was successfully sent using ::send function and this is what I sent to the server "GET http://www.codeproject.com/info/stuff/codeproject_w2k_bg.gif"
    :
    : And when I call ::recv (after a successful connection to the server), it will return after about a minute and return 0. Can anyone find a solution for this w/o using WinHTTP?
    :

    Just a guess, but shouldn't there be an extra newline after a HTTP request (2 in total)? (You can telnet to a webserver (on port 80) and try your commands interactively)
  • AseshAsesh Member Posts: 52
    : Just a guess, but shouldn't there be an extra newline after a HTTP request (2 in total)? (You can telnet to a webserver (on port 80) and try your commands interactively)
    :

    Why 2 new lines? I saw similar code in codeproject.com (URL followed by

    ) to do that but it used MFC for formatting URLs since I am into MFC, I just did what I thought was right. This is my code written in win32 (not the complete code):

    pHostent = ::gethostbyname(_T("www.codeproject.com"));

    server.sin_family = AF_INET;
    server.sin_port = ::htons(80);
    server.sin_addr.s_addr = *((ULONG *) pHostent->h_addr);
    nErrorTest = ::connect(socket, (SOCKADDR *) &server, sizeof(server));
    ::_stprintf(szSendData, _T("GET info/stuff/codeproject_w2k_bg.gif
    "));
    nErrorTest = ::send(socket, szSendData, ::lstrlen(szSendData), 0);
    nErrorTest = ::recv(socket, szRecvData, sizeof(szRecvData), 0);

    recv will return after about a minute and return 0. I tried to send the same command to the server with two new lines appended, recv returned immediately and returned 0 :(. Can you help me out.
  • PruyquePruyque Member Posts: 149
    [b][red]This message was edited by Pruyque at 2006-7-18 14:46:46[/red][/b][hr]
    : : Just a guess, but shouldn't there be an extra newline after a HTTP request (2 in total)? (You can telnet to a webserver (on port 80) and try your commands interactively)
    : :
    :
    : Why 2 new lines? I saw similar code in codeproject.com (URL followed by

    ) to do that but it used MFC for formatting URLs since I am into MFC, I just did what I thought was right. This is my code written in win32 (not the complete code):
    :
    : pHostent = ::gethostbyname(_T("www.codeproject.com"));
    :
    : server.sin_family = AF_INET;
    : server.sin_port = ::htons(80);
    : server.sin_addr.s_addr = *((ULONG *) pHostent->h_addr);
    : nErrorTest = ::connect(socket, (SOCKADDR *) &server, sizeof(server));
    : ::_stprintf(szSendData, _T("GET info/stuff/codeproject_w2k_bg.gif
    "));
    : nErrorTest = ::send(socket, szSendData, ::lstrlen(szSendData), 0);
    : nErrorTest = ::recv(socket, szRecvData, sizeof(szRecvData), 0);
    :
    : recv will return after about a minute and return 0. I tried to send the same command to the server with two new lines appended, recv returned immediately and returned 0 :(. Can you help me out.
    :


    I've got it working with this little piece of code:
    [code]
    #include
    #include
    #include

    int main(void)
    {
    char *buffer = "GET /info/stuff/codeproject_w2k_bg.gif
    ";

    char *rbuffer = malloc(2560);

    int sock = socket(PF_INET, SOCK_STREAM, 0);

    struct sockaddr_in sin;
    struct hostent *hent = gethostbyname("www.codeproject.com");

    printf("Get host by name: %p
    ", hent);

    sin.sin_family = AF_INET;
    sin.sin_port = htons(80);
    sin.sin_addr = *(struct in_addr *)hent->h_addr;
    printf("connect: %i
    ", connect(sock, (struct sockaddr *)&sin, sizeof(sin)));

    printf("send: %i
    ", send(sock, buffer, strlen(buffer), 0));
    printf("recv: %i
    ", recv(sock, rbuffer, 2560, 0));
    perror("recv");


    printf("%s
    ", rbuffer);

    return 0;
    }

    [/code]

    But now to figure out why your code does not work....

    There's a slash missing in your 'GET blah' string, but then the server should (and will) respond with a 'bad request', so that shouldn't cause problems with your recv.

    recv stores in a buffer szRecvData, sizeof(szRecvData) bytes, now if szRecvData is a pointer, sizeof(szRecvData) is 4 (or 8 on 64-bit hardware :), which would give a strange result, but not the result you get (I guess)... Now if szRecvData is an object (a struct of some kind), the sizeof would be fine, but szRecvData is not a pointer, so you should get a compiler error and else recv should return -1 (bad adress) or segfault...

    Hmmm, strange...

    Oh, and you were right on the newlines, only one is needed in a 'simple request' like we do here.


    [red]
    EDIT:

    A thought occured to me:
    RFC1945 states that a HTTP request should end in a CRLF (carriage return linefeed) not just a CR as you do with the
    in the 'GET'-request. So the server doesn't know you're done with your request (it's still waiting for LF), so it sends you no data. And thus your recv will read 0 bytes, because there's no data to read and it timesout. (This makes sense right?). If this is the case, just change the
    to
    and it should work, right?
    [/red]
  • AseshAsesh Member Posts: 52
    [b][red]This message was edited by Asesh at 2006-7-20 8:53:9[/red][/b][hr]
    It's not working mate. The samething's happening again with your code too :(. Anyway thanks for the help :)

  • PruyquePruyque Member Posts: 149
    : [b][red]This message was edited by Asesh at 2006-7-20 8:53:9[/red][/b][hr]
    : It's not working mate. The samething's happening again with your code too :(. Anyway thanks for the help :)
    :
    :

    Wait a minute...
    Are you using a windows box?
    If so, have you initialized the WinSock library by calling
    [code]
    WSAStartup();
    [/code]

    Here's a description of the function:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsastartup_2.asp

    Since I'm a Linux user (That's why I don't call it in my code), I'm not formiliar with this function and don't know what it's arguments should be, but a little Google'ing should come up with something usefull...

    Hope this will finally solve your problem,
    Pruyque

    (I'm going on holiday tomorrow, so I might not reply for a while:)
  • AseshAsesh Member Posts: 52
    : : [b][red]This message was edited by Asesh at 2006-7-20 8:53:9[/red][/b][hr]
    : : It's not working mate. The samething's happening again with your code too :(. Anyway thanks for the help :)
    : :
    : :
    :
    : Wait a minute...
    : Are you using a windows box?
    : If so, have you initialized the WinSock library by calling
    : [code]
    : WSAStartup();
    : [/code]
    :
    : Here's a description of the function:
    : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsastartup_2.asp
    :
    : Since I'm a Linux user (That's why I don't call it in my code), I'm not formiliar with this function and don't know what it's arguments should be, but a little Google'ing should come up with something usefull...
    :
    : Hope this will finally solve your problem,
    : Pruyque
    :
    : (I'm going on holiday tomorrow, so I might not reply for a while:)
    :

    Yes I am on windows anyway thanks :)
Sign In or Register to comment.