gpt4 book ai didi

c - 使用 select() 使套接字超时

转载 作者:行者123 更新时间:2023-12-02 08:20:55 25 4
gpt4 key购买 nike

我正在尝试制作一个简单的 port scanner在C中,终于到了最后阶段。我写了一个简单的函数来连接到端口上的服务器,如果端口关闭,应该会超时。我有以下测试用例:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char **argv) {
if(argc != 3) {
fprintf(stderr, "idiot.\n");
}

int sock = socket(AF_INET, SOCK_STREAM, 0);
int flags = fcntl(sock, F_GETFL, 0);

flags |= O_NONBLOCK;
fcntl(sock, F_SETFL, flags);

if(sock < 0) {
perror("socket()");
}

struct hostent *server = gethostbyname(argv[1]);

if (server == NULL) {
perror("gethostbyname()");
}

struct sockaddr_in server_addr;
bzero((char*)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
bcopy(server->h_addr, (char*)&server_addr.sin_addr.s_addr, server->h_length);
server_addr.sin_port = htons(atoi(argv[2]));

if(connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("connecting()");
}

fd_set rfds;
struct timeval tv;
int retval;

FD_ZERO(&rfds);
FD_SET(sock, &rfds);

tv.tv_sec = 3;
tv.tv_usec = 0;
retval = select(sock+1, &rfds, NULL, NULL, &tv);

if (retval == -1)
perror("select()");
else if (retval)
printf("port is open.\n");
else
printf("port is closed.\n");
return 0;
}

问题是,我通过它的任何端口都报告为打开。例如:

[nchambers@shell:~/SpinCloud/Chevron] [devel]$ ./testcase localhost 22 # sshd actually runs on this machine, so its correct
connecting(): Operation now in progress
port is open.
[nchambers@shell:~/SpinCloud/Chevron] [devel]$ telnet localhost 22
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6
^]

telnet> quit
Connection closed.
[nchambers@shell:~/SpinCloud/Chevron] [devel]$ ./testcase localhost 80 # but no webserver
connecting(): Operation now in progress
port is open.
[nchambers@shell:~/SpinCloud/Chevron] [devel]$ telnet localhost 80
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
[nchambers@shell:~/SpinCloud/Chevron] [devel]$

最佳答案

select 将某些内容报告为“可读”或“可写”的事实仅意味着 read/write 的尝试不会阻塞.它并不暗示read/write结果 会是什么。

注意:另外,您需要区分 connect 返回 EINPROGRESS 的情况(并轮询这种情况下的可写性)和其他失败。 (虽然也许你可以使用 TCP_KEEPCNTTCP_USER_TIMEOUT 代替?但是如果你像你应该的那样使用 getaddrinfo 并尝试所有地址可能同时出现,但每个地址之间有延迟)

此外,您应该认真考虑使用一种较新的替代方案,如果不是像 epoll 这样特定于系统的东西,至少是 poll(这是 POSIX) kqueue.

关于c - 使用 select() 使套接字超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37370210/

25 4 0
文章推荐: C段错误
文章推荐: java - split 二叉树
文章推荐: java - Android 中的线程
文章推荐: Haskell:嵌套仿函数上的 fmap
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com