非阻塞套接字连接的轮询中意外的回收值

问题描述 投票:0回答:1

我正在尝试创建无阻塞套接字连接。下面是相同的代码

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()的确切行为吗?

c sockets polling
1个回答
1
投票
来自头文件poll.h

#define POLLIN 0x0001 #define POLLPRI 0x0002 #define POLLOUT 0x0004 #define POLLERR 0x0008 #define POLLHUP 0x0010 #define POLLNVAL 0x0020

所以您的值0x28POLLERR|POLLNVAL组成,当轮询的文件描述符未打开时,可能会发生[]:

POLLNVAL Invalid request: fd not open (only returned in revents; ignored in events).

即使在poll.events中未要求时,也始终会出现这些值。
如您所见,套接字错误为111(首次调用getsockopt()),表示Connection refused。此后,由于不再连接该文件描述符,因此无法轮询。
© www.soinside.com 2019 - 2024. All rights reserved.