非阻塞套接字连接的轮询中意外的 revents 值
Unexpected revents value in poll for non blocking socket connect
我正在尝试创建一个非阻塞套接字连接。下面是相同的代码
#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
文档
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.)
当我打印 revents
的值时,它被设置为与 POLLOUT
不同的值。这是 poll()
的确切行为吗?
poll.revents
的值是位域。
来自头文件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
.
中没有要求也是如此
可以看到,socket错误是111
(第一次调用getsockopt()
),意思是Connection refused
。此后,文件描述符无法轮询,因为它不再连接。
我正在尝试创建一个非阻塞套接字连接。下面是相同的代码
#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
文档
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.)
当我打印 revents
的值时,它被设置为与 POLLOUT
不同的值。这是 poll()
的确切行为吗?
poll.revents
的值是位域。
来自头文件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
.
可以看到,socket错误是111
(第一次调用getsockopt()
),意思是Connection refused
。此后,文件描述符无法轮询,因为它不再连接。