查看局域网内所有在线用户 linux c

复制代码
/*
程序可以根据需要做适当的修改 使用-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 

posted @   cococo点点  阅读(3512)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
点击右上角即可分享
微信分享提示
^
关注