1

I'm programing a TCP/IP Socketserver.

My problem is, that my accept call is blocking and not accepting any new incomming connections when I (for example) telnet my server and do not send any data.

When I'm sending anything or quit the telnet accept stops blocking, I can handle the sent data and accept starts to accepting new incomming connections.

main() {
   socket = bind_listen();

   while(1) {
       user_socket = accept(socket);
       ssl = SSL_new(ctx);
       SSL_set_fd(ssl, user_socket);
       SSL_accept(ssl);

       event.data.fd = user_socket;
       event.events = EPOLLIN | EPOLLONESHOT;

       epoll_proof = epoll_ctl(poll_fd, EPOLL_CTL_ADD, user_socket, &event);
   }
}

There are several threads which epoll_wait() and handle data. Any idea? Thanks!

S. Braun
  • 143
  • 1
  • 7
  • 1
    Show your code, preferably minimal compilable example that exhibits the problem. – Nikolai Fetissov Aug 27 '12 at 16:28
  • Not enough detail is provided, but it sounds kind of like you're not using non-blocking sockets. (On POSIX this means `fcntl` to set `O_NONBLOCK`, on Windows this means something involving `ioctlsocket`, and in both it means handling `EAGAIN`/`EWOULDBLOCK` errors on all your socket calls.) – asveikau Aug 27 '12 at 16:30
  • I tried to add O_NONBLOCK but that did not fix my problem. – S. Braun Aug 27 '12 at 16:42
  • @nos epoll_ctl() is definitely not the problem. It is hanging in the accept() call. – S. Braun Aug 27 '12 at 16:44
  • Not exactly clear what the problem is. Try re-wording your description. – Nikolai Fetissov Aug 27 '12 at 16:45

3 Answers3

2

That's because your program is a single thread. In first step it waits for a connection, after that, when connection established, it waits for input.
You have several options to make it wait for several connections and accept them all : Threading, Select and fcntl .

Rsh
  • 7,214
  • 5
  • 36
  • 45
1

You can use a multiplexer, such as select or the poll family.

This will tell you when you can run accept w/out being blocked.

I think select is the easiest solution if you don't know how to use a multiplexer : http://linux.die.net/man/2/select

This will also avoid bad situations such as blocking read / write.

Intrepidd
  • 19,772
  • 6
  • 55
  • 63
  • So I need to call select or epoll first and wait for events on socket first? And when there is an event I have to accept()? – S. Braun Aug 27 '12 at 16:40
1

First off, you should poll the listening file descriptor (with select, poll or epoll/kqueue) and only call accept if it's ready to read.

Second, and more specifically, if you're going for edge-triggered epoll, you need to set your socket into non-blocking mode first. Then, when you're told that it's ready to read, you need to call accept in a loop until you return -1 with error EAGAIN or EWOULDBLOCK -- there may be multiple connection requests waiting at once, and edge-triggered polling only alerts you on state changes, so you need to drain the socket.

In a really, really naive fashion you could also do away with the polling and only work with non-blocking sockets, either in a busy loop or in a loop with a sort of sleep. But that's utterly wasteful, and doesn't buy you anything compared to the proper epoll/kqueue solution (or whatever polling mechanism your platform supplies).

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084