?
Solved

Socket problem: select() not returning when a new connection is available

Posted on 2003-03-21
4
Medium Priority
?
293 Views
Last Modified: 2010-04-21
I am trying to develop a simple socket server application on Linux (RedHat 8.0 Intel, kernel 2.4.18-14). I am using a non-blocking listening socket and check it with select() to see if new connections are available. I have this implemented on Win32 platform, and the whole server works fine. However, on Linux the select() call seems to never return an indication of a new connection.

Following is a reduced sample application that shows the problem. It does select() in 10 loops 500 ms each, but even though I connect during that time, select() still returns 0's. When the 10 loops are done, the sample calls accept(), and the connection is accepted.

Note that the sample code deliberately omits all error checking. For example, normally I would not call accept() if select() fails. But I think this sample illustrates the point quite clearly: connection is available as it gets accept()'ed fine, but still select() does not see the connection.

Any ideas what could be wrong? I think this is quite a basic usage of select() and accept().

The sample code follows:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>

// Some defines from Win32 world.
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define SOCKET int
#define SOCKADDR_IN struct sockaddr_in

int main()
{
  SOCKET sd;
  int retval;

  sd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
  // Set socket to non-blocking mode.
  unsigned long Flags;
  Flags = fcntl(sd, F_GETFL, 0);
  Flags = Flags | O_NONBLOCK;
  fcntl (sd, F_SETFL, Flags);

  SOCKADDR_IN LocalAddr;

  // Set server socket's address info.
  LocalAddr.sin_family = AF_INET;
  LocalAddr.sin_port = htons(8541);
  LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);

  // Bind the socket to the given port.
  if (bind(sd, (struct sockaddr *)&LocalAddr, sizeof(LocalAddr)) == SOCKET_ERROR) {
    printf ("bind() failed.\n");
    return (1);
  }

  // Set the socket to listening state.
  retval=listen(sd, SOMAXCONN);
  if (retval) {
    printf ("listen() failed.\n");
  }

  SOCKET newsd;
  SOCKADDR_IN Accepted;
  socklen_t Size;

  // Try accepting a new connection.
  Size=sizeof(Accepted);
  newsd=accept(sd, (struct sockaddr *)&Accepted, &Size);
  if (newsd!=INVALID_SOCKET) {
    printf ("Connection was accepted.\n");
  }
  else {
    printf ("First accept() failed. Starting to poll...\n");
  }

  fd_set fdread;
  int Timeout=10;
  do {
    struct timeval timeout={0,500000};
    int n;

    FD_ZERO (&fdread);
    FD_SET (sd, &fdread);
    n=1;
    retval=select(n, &fdread, NULL, &fdread, &timeout);
    printf ("select() returned %d.\n", retval);
  } while (retval==0 && Timeout--);

  // Try accepting the new connection.
  newsd=accept(sd, (struct sockaddr *)&Accepted, &Size);
  if (newsd!=INVALID_SOCKET) {
    printf ("Connection was accepted.\n");
  }
  else {
    printf ("accept() failed.\n");
  }

  // From here on we don't really care what happens with the socket.
  // (current client keeps it open so that socktest won't be able to
  // bind if run immediately again - this situation fixes itself when
  // the timeout in the client expires).

  close (newsd);
  close (sd);
  pause();  // Let the user exit the app with Ctrl+C.
}


Sample output:

First accept() failed. Starting to poll...
select() returned 0.
select() returned 0.
select() returned 0.
select() returned 0.
select() returned 0.  <== At this point I connect from another computer.
select() returned 0.
select() returned 0.
select() returned 0.
select() returned 0.
select() returned 0.
select() returned 0.
Connection was accepted.  <== The connection is accepted only here.
0
Comment
Question by:mnoromaa
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 5

Expert Comment

by:ecw
ID: 8184648
Don't use a non-blocking socket.
0
 

Author Comment

by:mnoromaa
ID: 8185896
Any specific reason why I shouldn't use a non-blocking socket? All documentation suggests that non-blocking sockets are usable.
0
 

Accepted Solution

by:
mikkon987 earned 300 total points
ID: 8186498
> n=1;
> retval=select(n, &fdread, NULL, &fdread, &timeout);

Try:

n=sd+1;

n should be the highest numbered descriptor plus 1, NOT the number of descriptors!
0
 

Author Comment

by:mnoromaa
ID: 8186540
Indeed, this did the trick!

Thank you!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses
Course of the Month8 days, 5 hours left to enroll

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question