我很难理解无块套接字以及如何将它们用于网络扫描程序。我理解我应该做的是使用以下内容将套接字设置为非阻塞:
fcntl(sockfd , F_SETFL, O_NONBLOCK);
然后只需调用connect,它应该返回EINPROGRESS。 之后我应该使用这样的选择:
if (select(sockfd + 1, NULL, &fdset, NULL, &tv) == 1)
其中tv是timeval结构的地址。
然后
getsockopt(sockfd , SOL_SOCKFD ET, SO_ERROR, &so_error, &len);
知道操作是否成功,但总是如此。
有人可以给我一个小c程序的例子 检查ip是否正常,解释整个事情? 我对如何做到这一点感到非常无能为力。
答案 0 :(得分:0)
SO_ERROR
返回套接字的最后一个错误代码并重置它。如果select()
报告套接字是可写的,则连接成功,无需检查错误代码。如果select()
报告超时,则连接仍在进行中,因此错误代码仍为EINPROGRESS
,只需关闭套接字并继续。要检测连接失败,请将套接字置于fd_set
的{{1}}参数中的exceptfds
,然后仅在select()
仍设置SO_ERROR
时检查fd_set
当select()
返回时> 0
fcntl(sockfd, F_SETFL, O_NONBLOCK);
res = connect(sockfd, ...);
if (res == -1)
{
if (errno != EINPROGRESS)
{
// connect failed, do something...
return;
}
fd_set wfd, efd;
FD_ZERO(&wfd);
FD_SET(sockfd, &wfd);
FD_ZERO(&efd);
FD_SET(sockfd, &efd);
timeval tv;
...
res = select(sockfd+1, NULL, &wfd, &efd, &tv);
if (res == -1)
{
// select failed, do something...
close(sockfd);
return;
}
if (res == 0)
{
// connect timed out...
close(sockfd);
return;
}
if (FD_ISSET(sockfd, &efd))
{
// connect failed, do something...
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
close(sockfd);
return;
}
}
// connected !