Jump to content
  • Advertisement
Sign in to follow this  
basananas

[C++] Winsock and blocking recv-calls

This topic is 5033 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, how are you doing? I've been working on a webpage fetcher, but I've encountered a problem: when I request a webpage, although the downloading of the page itself takes only two seconds, the last recv (which will be checked for zero to exit) waits 14 seconds to return 0. One way of solving is is to look at the content-length headers, but not every server does reply with a full header. So at some servers, the problem still exists! Mozilla Firefox doesn't have a problem with it and loads every page quickly so it must use some other method than I'm doing. My question: does anybody know how I can change my code so that it doesn't get blocked? (by the way, I couldn't find anything in the msdn documentation, which I also noted to be very ANSI-non-friendly) Here's my code I have so far:
#include <cstdio>           // Needed for printf()
#include <cstdlib>          // Needed for exit()
#include <string.h>         // Needed for strcpy() and strlen()
#include <windows.h>        // Needed for all Winsock stuff

#include <iostream>
using namespace std;

#define  BUF_SIZE            4096     // Buffer size

int main(void)
{
  WORD wVersionRequested = MAKEWORD(1,1);    // Stuff for WSA functions
  WSADATA wsaData;                           // Stuff for WSA functions

  unsigned int         server_s;             // Server socket descriptor
  struct sockaddr_in   server_addr;          // Server Internet address
  char                 in_buf[BUF_SIZE];     // Input buffer for response
  int                  retcode;              // Return code

  // This stuff initializes winsock
  int test = WSAStartup(wVersionRequested, &wsaData);
  if (test != NO_ERROR) {
    printf("Error at WSAStartup()\n");
    return -1;
  }

  // Create a socket
  server_s = socket(AF_INET, SOCK_STREAM, 0);

  if ( server_s == INVALID_SOCKET ) {
    printf( "Error at socket(): %d\n", WSAGetLastError() );
    WSACleanup();
    return -1;
  }

  char * ip_addr = "80.249.158.5";
  int port_num = 6969;

  // Fill-in the Web server socket's address information
  server_addr.sin_family = AF_INET;                 // Address family to use
  server_addr.sin_port = htons(port_num);           // Port num to use
  server_addr.sin_addr.s_addr = inet_addr(ip_addr); // IP address to use

  // Do a connect (connect() blocks)
  retcode = connect(server_s, (struct sockaddr *)&server_addr,
                    sizeof(server_addr));
  if (retcode != 0)
  {
    printf("ERROR - connect() failed \n");
    WSACleanup();
    return -1;
  }

  char * get_string = "GET /scrape HTTP/1.1\r\n"
                      "Connection: Keep-Alive\r\n"
                      "User-Agent: Client\r\n"
                      "Accept: text/html, image/jpeg, image/png, text/*, image/*, */*\r\n"
                      "Accept-Encoding: gzip, deflate\r\n"
                      "Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5\r\n"
                      "Accept-Language: en\r\n"
                      "Host: 80.249.158.5:6969\r\n\r\n";

  // Send a GET to the Web server
  send(server_s, get_string, strlen(get_string), 0);

  // Open file
  FILE *fp = fopen( "page.txt", "wb" );

  // Receive from the Web server
  //  - The return code from recv() is the number of bytes received
cout << "waiting for server" << endl;
  retcode = recv(server_s, in_buf, BUF_SIZE, 0);
cout << retcode << "bytes received" << endl;
  while ((retcode > 0) || (retcode == -1) && retcode != WSAECONNRESET)
  {
    if (retcode == -1)
    {
      printf("ERROR - recv() failed \n");
      exit(1);
    }
    fwrite(in_buf, 1, retcode, fp);

    retcode = recv(server_s, in_buf, BUF_SIZE, 0);
cout << retcode << "bytes received" << endl;
  }

  // Close file
  fclose(fp);

  // Close all open sockets
  closesocket(server_s);

  // This stuff cleans-up winsock
  WSACleanup();
}



Oh and another thing before I forget: is it advisable to use winsock2 instead of winsock? Now I'm using Winsock but I don't see a lot of difference between the two libs. Cheers, Bas

Share this post


Link to post
Share on other sites
Advertisement

Do a google search for non blocking sockets, I cant remember of hand how you do it. Its fairly straight forward though.

You should be fine with Winsock 1.1.

Share this post


Link to post
Share on other sites
It might be straightfoward, but it's not well documented on the Internet. It would be very helpful if someone would show a snipplet of code in which a non blocking socket is set up. That's all I need; I think it's pretty strange that msdn doesn't show how to create a non blocking socket... I have found how to do it in GNU but MS's reference is quite appauling.

Good day,
Bas

Share this post


Link to post
Share on other sites
You have said that you are writting a web page fetcher. With this is mind, would it not be useful to look into Multi-Threading sockets, which would also solve your recv() call blocking.

Maybe you've already thought of this, its just your code didn't hint at it!

Share this post


Link to post
Share on other sites
Hey Kalligan. I have solved the recv-blocking problems; it seemed that I had found a bad tutorial on the Internet.... after tweaking a bit I got non-blocking recv. After that, I've started working on threading. I've never heard of mult-threaded sockets and never though about it, but at the moment I've already programmed a large part of the program using the pthread lib and it's working properly.

Bas

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!