I am trying to create a non-blocking socket connect. Below is the code for the same
#include<fcntl.h>
#include<errno.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<strings.h>
#include<string.h>
#include <sys/poll.h>
#define MAX_EPOLL_EVENTS 64
void perror(char const * s);
int main()
{
int result, n, rc;
socklen_t result_len = sizeof(result);
struct pollfd fds[1];
int sockfd, flags;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
int len = sizeof(int);
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(20000);
server_addr.sin_addr.s_addr = inet_addr("10.0.1.17");
n = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (n != 0)
//if (errno != EINPROGRESS) {
perror("Connection gone wrong");
fds[0].fd = sockfd;
fds[0].events = POLLOUT;
fds[0].revents = 0;
while(1){
rc = poll(fds, (nfds_t)1, 10*1000);
printf("value of poll result is - %d- %d\n", rc, errno);
if (rc == 1){
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &result, &result_len);
printf("%d\n", result);
}
printf("code for POLLOUT - %d\n", POLLOUT);
printf("revents - %d\n", fds[0].revents);
if(result == 0){
break;
}
}
}
Output:
Connection gone wrong: Operation now in progress
value of poll result is - 1- 115
111
code for POLLOUT - 4
revents - 28
value of poll result is - 1- 115
0
code for POLLOUT - 4
revents - 20
As per the poll
documentation
The field revents is an output parameter, filled by the kernel with the events that actually occurred. The bits returned in revents can include any of those specified in events, or one of the values POLLERR, POLLHUP, or POLLNVAL. (These three bits are meaningless in the events field, and will be set in the revents field whenever the corresponding condition is true.)
When I print the value of revents
, that is set to a different value to POLLOUT
. Is this the exact behaviour of poll()
?
The value of poll.revents
is a bitfield.
From the header file poll.h
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
So your value 0x28
is comprised of POLLERR|POLLNVAL
, which can occur, when the filedescriptor polled for is not open:
POLLNVAL Invalid request: fd not open (only returned in revents; ignored in events).
These values can always occur, even when not asked for in poll.events
.
As you can see, the socket error is 111
(first call to getsockopt()
), which means Connection refused
. After this, the filedescriptor is invalid to poll for, because it is no longer connected.