C 非阻塞套接字连接的轮询中出现意外的revents值
我正在尝试创建一个非阻塞套接字连接。下面是相同的代码C 非阻塞套接字连接的轮询中出现意外的revents值,c,sockets,polling,C,Sockets,Polling,我正在尝试创建一个非阻塞套接字连接。下面是相同的代码 #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<str
#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;
}
}
}
根据投票
文件
字段revents是一个输出参数,由内核用实际发生的事件填充。revents中返回的位可以包括events中指定的任何位,也可以包括POLLERR、POLLHUP或POLLNVAL中的一个值。(这三个位在事件字段中没有意义,只要相应的条件为真,就会在revents字段中设置。)
当我打印
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
组成,当轮询的文件描述符未打开时,可能会出现这种情况:
即使在poll.events
中未请求这些值,这些值也始终会出现
如您所见,套接字错误是
111
(第一次调用getsockopt()
),这意味着连接被拒绝。在此之后,filedescriptor无法轮询,因为它不再连接。感谢您的明确解释。在第二种情况下,revents
的值为20,即POLLNVAL
,那么它是否表示套接字尚未准备好写入?但我仍然能够写入套接字。@奇怪您不能写入未连接的套接字。它应该返回一个EPIPE
,检查返回值是的,很抱歉。如果revents
为20,则无法写入。只有当revents
为4时,它才能写入。我只是在20和4之间搞混了。非常感谢。
#define POLLIN 0x0001
#define POLLPRI 0x0002
#define POLLOUT 0x0004
#define POLLERR 0x0008
#define POLLHUP 0x0010
#define POLLNVAL 0x0020
POLLNVAL
Invalid request: fd not open (only returned in revents; ignored in events).