views:

425

answers:

1

hi everybody!

I'm running out of file descriptors when my program can't connect another host. The close() system call doesn't work, the number of open sockets increases. I can se it with

cat /proc/sys/fs/file-nr

Print from console:

connect: No route to host

close: Bad file descriptor

connect: No route to host

close: Bad file descriptor

..

Code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <iostream>
using namespace std;

#define PORT            1238
#define MESSAGE         "Yow!!! Are we having fun yet?!?"
#define SERVERHOST      "192.168.9.101"

void
write_to_server (int filedes)
{
  int nbytes;

  nbytes = write (filedes, MESSAGE, strlen (MESSAGE) + 1);
  if (nbytes < 0)
    {
      perror ("write");
    }
}

void
init_sockaddr (struct sockaddr_in *name,
               const char *hostname,
               uint16_t port)
{
  struct hostent *hostinfo;

  name->sin_family = AF_INET;
  name->sin_port = htons (port);
  hostinfo = gethostbyname (hostname);
  if (hostinfo == NULL)
    {
      fprintf (stderr, "Unknown host %s.\n", hostname);
    }
  name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
}

int main() 
{
 for (;;)
 {
  sleep(1);
  int sock;
  struct sockaddr_in servername;

  /* Create the socket. */
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
  {
   perror ("socket (client)");
  }

  /* Connect to the server. */
  init_sockaddr (&servername, SERVERHOST, PORT);
  if (0 > connect (sock,
    (struct sockaddr *) &servername,
    sizeof (servername)))
  {
   perror ("connect");
   sock = -1;
  }

  /* Send data to the server. */
  if (sock > -1)
   write_to_server (sock);
  if (close (sock) != 0)
   perror("close");
 }
return 0;
}

Fix:

  if (0 > connect (sock,
    (struct sockaddr *) &servername,
    sizeof (servername)))
  {
   perror ("connect");
  }

  else
   write_to_server (sock);

  if (close (sock) != 0)
   perror("close");
+7  A: 

It looks like the problem is in the structure of your program. Every time through your infinite loop, you're creating a new socket. I'd suggest moving this out of the loop and re-using it.

If you'd like to just fix the way you're doing it now though, use close inside the "connect" failed if statement you have now. The descriptor is allocated by the 'socket' call and only connected with the 'connect' call. By setting your 'sock' variable to -1, you're throwing away the descriptor allocated by 'socket'. Call close, then set it to -1 and you should be set.

Rakis
+1: Even though connect fails, you still need to close the socket instead of throwing away the handle.
Jon Cage
thx problem fixed