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. 总结
代码不难,关键是能提高效率,有时候简单的东西反而更好,继续努力
作者:ballwql
本文为作者原创,版权所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。