/*
程序可以根据需要做适当的修改
使用-t 最好设置成5秒到10秒左右。否则将可能检测不到下面的第一种情况。
1.如果局域网内一台电脑使用了应用层防火墙比如天网之类,会connect超时。对方在线
2.connect success 连接成功,对方在线
3.connect refused 拒绝连接,对方在线
4.no route 连续发送5个arp请求(没有结果)和一个dns查询后(返回nxdomain),内核产生no route的错误。对方不在线
*/
#include
"
stdio.h
"
#include
"
stdlib.h
"
#include
"
string.h
"
#include
"
unistd.h
"
#include
"
sys/types.h
"
#include
"
sys/time.h
"
#include
"
sys/socket.h
"
#include
"
arpa/inet.h
"
#include
"
netinet/in.h
"
#include
"
netdb.h
"
#include
"
fcntl.h
"
#include
"
errno.h
"
void
usage() {
printf(
"
use format:\n\t-s startip\n\t-e endip\n\t-t connect_timeout\n\t-p port\n
"
);
exit(
-
1
);
}
int
main(
int
argc,
char
**
argv)
{
int
start_ip =
1
;
int
end_ip =
254
;
//设置超时时限
int
time_connect =
10
;
//设置端口号
int
port =
8888
;
int
opt;
while
((opt = getopt(argc, argv,
"
s:e:t:p:
"
)) != -
1
) {
switch
(opt) {
case
'
s
'
:start_ip = atoi(optarg);
break
;
case
'
e
'
:end_ip = atoi(optarg);
break
;
case
'
t
'
:time_connect = atoi(optarg);
break
;
case
'
p
'
:port = atoi(optarg);
break
;
case
'
?
'
:usage();
break
;
}
}
printf(
"
-----------------------------------------------------------------------------------------------------\n
"
);
printf(
"
\t scan will use 192.168.1.%d -> 192.168.1.%d with connect timeout %d in port %d\n
"
, start_ip, end_ip, time_connect, port);
printf(
"
-----------------------------------------------------------------------------------------------------\n
"
);
struct
timeval timeout;
fd_set wset;
fd_set rset;
char
straddr[
100
];
//按照地址1~254进行扫描
for
(
int
i=start_ip; i<end_ip+
1
; i++
) {
//套接字
int
sockfd = socket(AF_INET, SOCK_STREAM,
0
);
if
(sockfd == -
1
)perror(
"
socket()
"
);
sprintf(straddr,
"
192.168.1.%d\0
"
, i);
fprintf(stderr,
"
scan %s\t
"
, straddr);
//设置地址信息
struct
sockaddr_in server_addr;
server_addr.sin_family
=
AF_INET;
if
(inet_pton(AF_INET, straddr, &(server_addr.sin_addr)) !=
1
)perror(
"
inet_pton()
"
);
server_addr.sin_port
=
htons(port);
int
flags;
if
((flags = fcntl(sockfd, F_GETFL,
0
)) <
0
)perror(
"
fcntl()
"
);
if
(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)<
0
)perror(
"
fcntl()
"
);
//连接
int
result = connect(sockfd, (
struct
sockaddr*)(&server_addr),
sizeof
(server_addr));
if
(result == -
1
) {
if
(errno ==
EINPROGRESS) {
timeout.tv_sec
=
10
;
timeout.tv_usec
=
0
;
if
(time_connect >=
100
) {
timeout.tv_sec
=
0
;
timeout.tv_usec
=
time_connect;
}
else
if
(time_connect >
0
) {
timeout.tv_sec
=
time_connect;
timeout.tv_usec
=
0
;
}
//select机制,初始化
FD_ZERO(
&
wset);
//添加套接字
FD_SET(sockfd,
&
wset);
rset
=
wset;
int
n =
select
(sockfd+
1
, &rset, &wset,
0
, &
timeout);
if
(n == -
1
&& errno!=
EINTR) {
perror(
"
select() error
"
);
}
else
if
(n >
0
) {
int
optval;
int
optlen =
4
;
if
(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (
void
*)&optval, (socklen_t*)&optlen) <
0
)perror(
"
getsockopt()
"
);
if
(optval ==
0
) {
fprintf(stderr,
"
success select\n
"
);
}
else
{
fprintf(stderr,
"
failed select %d:%s\n
"
, optval, strerror(optval));
}
}
else
if
(n ==
0
) {
fprintf(stderr,
"
connect timeout\n
"
);
}
}
else
{
close(sockfd);
perror(
"
connect()
"
);
}
}
else
{
printf(
"
connect() success\n
"
);
close(sockfd);
continue
;
}
close(sockfd);
}
return
0
;
}
已添加注释~~~~~~~~~~~~~~~~~~

