我正在尝试创建无阻塞套接字连接。下面是相同的代码
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;
}
}
}
输出:
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
根据poll
文档
字段revents是一个输出参数,由内核填充实际发生的事件。 revents中返回的位可以包括事件中指定的任何位,或值POLLERR,POLLHUP或POLLNVAL之一。 (这三个位在事件字段中无意义,只要相应条件为真,就会在revents字段中设置。)
当我打印revents
的值时,将其设置为与POLLOUT
不同的值。这是poll()
的确切行为吗?
poll.h
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
所以您的值0x28
由POLLERR|POLLNVAL
组成,当轮询的文件描述符未打开时,可能会发生[]:
POLLNVAL Invalid request: fd not open (only returned in revents; ignored in events).
即使在poll.events
中未要求时,也始终会出现这些值。如您所见,套接字错误为111
(首次调用getsockopt()
),表示Connection refused
。此后,由于不再连接该文件描述符,因此无法轮询。