/*
程序可以根據需要做適當的修改
使用-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
;
}
已添加注釋~~~~~~~~~~~~~~~~~~
?轉自: http://blog.chinaunix.net/uid-9078996-id-2010266.html ?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

