About Select system call
The select() function shall examine the file descriptor sets whose addresses are passed in the readfds, writefds,
and errorfds parameters to see whether some of their descriptors are ready for reading, are ready for writing, or
have an exceptional condition pending, respectively.
int select(int nfds, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict errorfds,
struct timeval *restrict timeout);
There are many usages of select() system call, Here is one usage in networking applications, The use of select system call is to make non-blocking call in Linux.
how to make a non-blocking connect() in Linux
1. create socket using socket(),
2. set the file descriptor to non-blocking mode using fcntl(2)
fnctl (fd, SETFL, fcntl(fd, GETFL) | O_NONBLOCK)
3. call connect() - since you have set the socket to non-blocking, it will
return right away with a result of EINPROGRESS.
4. Now
a) Go into a loop and keep calling connect() - as long as it
has not completed it will return EALREADY (see man page for
connect()). This is simple but not a good solution. check below solution
using select to avoid loop wait.
OR
b) Use select(2), selecting the socket for write. When the connect is
finished, the select should return and show the socket as writeable.
Using select() can be tricky, but will be more efficient, since
select() will block until the connect has finished and you are not
wasting CPU in a tight loop.
/* No loop required */
fd_set write_set;
FD_ZERO(write_set);
FD_SET(write_set, fd);
select (fd+1, 0, write_set, 0, 0);
File descriptor masks of type fd_set can be initialized and tested with FD_CLR(), FD_ISSET(), FD_SET(), and
FD_SET(fd, fdsetp) shall add the file descriptor fd to the set pointed to by fdsetp. If the file descriptor fd is
already in this set, there shall be no effect on the set, nor will an error be returned.
FD_ZERO(fdsetp) shall initialize the descriptor set pointed to by fdsetp to the null set. No error is returned if
the set is not empty at the time FD_ZERO() is invoked.
The original Standard can be obtained online at http://www.opengroup.org/unix/online.html
The select() function shall examine the file descriptor sets whose addresses are passed in the readfds, writefds,
and errorfds parameters to see whether some of their descriptors are ready for reading, are ready for writing, or
have an exceptional condition pending, respectively.
int select(int nfds, fd_set *restrict readfds,
fd_set *restrict writefds, fd_set *restrict errorfds,
struct timeval *restrict timeout);
There are many usages of select() system call, Here is one usage in networking applications, The use of select system call is to make non-blocking call in Linux.
how to make a non-blocking connect() in Linux
1. create socket using socket(),
2. set the file descriptor to non-blocking mode using fcntl(2)
fnctl (fd, SETFL, fcntl(fd, GETFL) | O_NONBLOCK)
3. call connect() - since you have set the socket to non-blocking, it will
return right away with a result of EINPROGRESS.
4. Now
a) Go into a loop and keep calling connect() - as long as it
has not completed it will return EALREADY (see man page for
connect()). This is simple but not a good solution. check below solution
using select to avoid loop wait.
OR
b) Use select(2), selecting the socket for write. When the connect is
finished, the select should return and show the socket as writeable.
Using select() can be tricky, but will be more efficient, since
select() will block until the connect has finished and you are not
wasting CPU in a tight loop.
/* No loop required */
fd_set write_set;
FD_ZERO(write_set);
FD_SET(write_set, fd);
select (fd+1, 0, write_set, 0, 0);
File descriptor masks of type fd_set can be initialized and tested with FD_CLR(), FD_ISSET(), FD_SET(), and
FD_SET(fd, fdsetp) shall add the file descriptor fd to the set pointed to by fdsetp. If the file descriptor fd is
already in this set, there shall be no effect on the set, nor will an error be returned.
FD_ZERO(fdsetp) shall initialize the descriptor set pointed to by fdsetp to the null set. No error is returned if
the set is not empty at the time FD_ZERO() is invoked.
The original Standard can be obtained online at http://www.opengroup.org/unix/online.html
Comments