TCP Socket Port Check

    写了两个小程序,主要是用于linux和windows下TCP端口的检测,自带的telnet无法满足我批量检测的需要,在我眼里这类端口检测程序最为关键的是超时的限制,若端口不能却要老久才返回结果,有点不爽,在不改系统默认超时时间的前提上,引入socket的非阻塞模式达到超时限制的目的,下面是具体程序

 

1. windows下的tcp端口检测程序

简介:引入select模式作为超时限制

 1 //TCP Port Check program in windows
 2 
 3 
 4 #include <stdio.h>
 5 #include <winsock2.h>
 6 
 7 #pragma comment(lib,"ws2_32.lib")
 8 
 9 
10 int main(int argc, char *argv[])
11 {
12     SOCKET sockfd;    
13     SOCKADDR_IN sockaddr;
14     int port;
15     unsigned long ip;
16     WSADATA wsa;
17     int timeout=2,ret;
18     struct timeval tv;
19     struct fd_set fs;
20     unsigned long ul = 1;
21     
22 
23     if(argc != 4)
24     {
25         printf("Usage: %s IP Port TimeOut\n",argv[0]);
26         return -1;
27     }
28     if((ip=inet_addr(argv[1]))==INADDR_NONE)
29     {
30         printf("IP Address Error\n");
31         return -1;
32     }
33     if((port=atoi(argv[2]))==0)
34     {
35         printf("Port Error\n");
36         return -1;
37     }
38     if((timeout=atoi(argv[3]))==0)
39     {
40         printf("Timeout Error\n");
41         return -1;
42     }
43     WSAStartup(MAKEWORD(1,1),&wsa);    //initialize Ws2_32.dll
44 
45     if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)    //create a tcp socket
46     {
47         printf("Create socket fail!\n");
48         return -2;
49     }
50     //socket non-block mode set
51     if((ret = ioctlsocket(sockfd, FIONBIO, (unsigned long*)&ul))==SOCKET_ERROR)
52     {
53         closesocket(sockfd);
54         return -1;
55     }
56     sockaddr.sin_family = AF_INET;
57     sockaddr.sin_port = htons(port);
58     sockaddr.sin_addr.S_un.S_addr = inet_addr(argv[1]);
59 
60     //connect to target ip with port
61     connect(sockfd, (SOCKADDR *)&sockaddr, sizeof(sockaddr));
62     
63     tv.tv_sec = timeout;
64     tv.tv_usec = 0;
65     FD_ZERO(&fs);
66     FD_SET(sockfd,&fs);  
67     ret = select(sockfd+1,NULL,&fs,NULL,&tv);
68     if(ret<0)
69     {
70         printf("Select Error\n");
71         closesocket(sockfd);
72         return -1;
73     }
74     else if(ret == 0)
75     {
76         printf(" %s %d Connect fail!\n",argv[1],port);
77         closesocket(sockfd);
78         return -1;
79     }
80     else
81     {
82         printf(" %s %d Connected success!\n",argv[1],port);
83         closesocket(sockfd);
84     }
85     WSACleanup(); //clean up Ws2_32.dll 
86     return 0;
87 }

 

2. Linux下TCP端口检测程序

#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <time.h>
#include <errno.h>
int main(int argc, char *argv[])
{
        int sockfd=socket(AF_INET,SOCK_STREAM,0);
        struct sockaddr_in client;
        char ip[20];
        int port;
        int timeout;
        struct timeval tv;
        if(argc != 4)
        {
                printf("Usage : %s ip port timeout\n", argv[0]);
                exit(1);
        }
        strcpy(ip, argv[1]);
        port = atoi(argv[2]);
        timeout = atoi(argv[3]);
        
        bzero(&client, sizeof(struct sockaddr_in));
        client.sin_family = AF_INET;
        client.sin_addr.s_addr = inet_addr(ip);
        client.sin_port = htons(port);

        tv.tv_sec = 5;
        tv.tv_usec = 0;

        //set timeout with setsockopt
        if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&tv, sizeof(tv))<0)
        {
            perror("setsockopt failed\n");
            exit(1);
        }

        if(setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,(char*)&tv, sizeof(tv))<0)
        {
            perror("setsockopt failed\n");
            exit(1);
        }
        if(!connect(sockfd,(struct sockaddr*)&client,sizeof(struct sockaddr_in)))
        {
                printf("connect ok\n");

        }else{
                printf("connect fail\n");
        }
    close(sockfd);
        return 0;
}

3. 总结

    代码不难,关键是能提高效率,有时候简单的东西反而更好,继续努力

posted @ 2015-01-18 14:18 ballwql 阅读(...) 评论(...) 编辑 收藏