• C

Connection hangs using C Socket Library

I'm using the C socket library to create a program which downloads and processes certain html documents.

Sometimes, however, I come accross a site that works fine on a browser or with wget, but will cause my program to hang endlessly when I try to download it using the C socket library.  

The routine where the data is actually downloaded is this:

      char buf[MAXRECV + 1];
      int status;
      while (status != 0) {
            memset(buf, 0, MAXRECV + 1);
            status = ::recv(m_sock, buf, MAXRECV, 0); // this statement causes the hang
      }

An example website which works normally through a browser, but hangs with C socket library is http://natzoo.si.edu/Animals/WebCams/

Can anyone offer some possible explanations for this?

Thanks.
chsalviaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ikeworkCommented:
seems you run sockets in synchronous mode, so recv is waiting for incoming data, if you want it to exit, if nothing is available, you have to run sockets in asynchronous mode (nonblocking sockets).

here is an example, how to set a socket nonblocking (non-win-example) :

http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWdev/NETPROTO/p37.html


ike

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ikeworkCommented:
here is another one:

http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzab6/rzab6xnonblock.htm

take a look to the ioctl() - function. with this you set the socket nonblocking ...
ikeworkCommented:
// set socket non-blocking:

int    on = 1;
rc = ioctl(listen_sd, FIONBIO, (char *)&on);
if (rc < 0)
{
   perror("ioctl() failed");
   close(listen_sd);
   exit(-1);
}
ikeworkCommented:
and the same for windows:
/*
int ioctlsocket(
  SOCKET s,
  long cmd,
  u_long* argp
);
*/

int    on = 1;
rc = ioctlsocket(listen_sd, FIONBIO, (char *)&on);
if (rc < 0)
{
   perror("ioctlsocket() failed");
   close(listen_sd);
   exit(-1);
}
MysidiaCommented:
Your code doesn't check the return value of  recv() for an error.


Should have something such as...
#include <errno.h>

...
...
 status = ::recv(m_sock, buf, MAXRECV, 0); // this statement causes the hang
if (status == -1 &&   errno !=  EINTR  && errno != EAGAIN) {
    perror("socket");
        break;
}

Use select() to wait for a status change on the socket before performing the recv call.


    char buf[MAXRECV + 1];
    fd_set readset;
    int status, temp;

     while (status != 0)
     {
          FD_ZERO(&readset);
          FD_SET(m_sock, &readset);

          memset(buf, 0, MAXRECV + 1);
          if ((temp = select(m_sock + 1, &readset, NULL, NULL, NULL) )  > 0 ) {                        
              status = ::recv(m_sock, buf, MAXRECV, 0); // this statement causes the hang
              if (status == -1) {
                   perror("recv");
                   break;
              }
          }
          else if (temp == -1) {
               if (errno != EINTR) {  perror("select");  }
          }
     }

You really don't need non-blocking sockets  for a simple interactive client application: turning on
the non-blocking flag is ONE thing, but there are other major changes you would need to make
to properly use a non-blocking socket.

To use a non-blocking socket, you need to flag it non-blocking just after creation and wait for
a positive select()  response on the socket before each operation on the descriptor, including a connect()
or write().

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.