带超时时间的telnet该怎么玩?------检测tcp是否可连接时经常用到(本文仅给出linux版本,之前博客也有Windows版本的)
2017-12-18 19:52
721 查看
前面说过, 利用ping命令探测网络是否可通, 但很多时候, 服务端或者防火墙禁止了ping命令, 也就是说, ping不通, 不表示网络不通, 所以仍有可能能建立tcp连接。怎么检测tcp连接是否可通呢? 用telnet命令就可以搞起, 但问题是, 很多时候(尤其是批量探测的时候), 我们需要给telnet命令设置一个超时时间, 很遗憾, 这是telnet命令所不支持的。 那要怎么搞? 还是自己写程序吧, 如下:
批量探测怎么搞呢? 来看看:
#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <malloc.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <stdarg.h> #include <fcntl.h> #include <time.h> int telnetCheckTcp(const char *ip, int port, int tSecond) { int sockClient = socket(AF_INET, SOCK_STREAM, 0); int iFinal = 0; struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr(ip); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(port); fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); // 返回-1不一定是异常 if (iRet != 0) { if(errno != EINPROGRESS) { iFinal = -1; } else { struct timeval tm = {tSecond, 0}; fd_set wset, rset; FD_ZERO(&wset); FD_ZERO(&rset); FD_SET(sockClient, &wset); FD_SET(sockClient, &rset); int time1 = time(NULL); int n = select(sockClient + 1, &rset, &wset, NULL, &tm); int time2 = time(NULL); if(n < 0) { iFinal = -2; } else if(n == 0) { iFinal = -3; } else if (n == 1) { if(FD_ISSET(sockClient, &wset)) { iFinal = 0; fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); } else { iFinal = -4; } } else { iFinal = -5; } } } close(sockClient); return iFinal; } int main(int argc, char *argv[]) { if(argc != 4) { printf("error\n"); return -1; } int iFinal = telnetCheckTcp(argv[1], atoi(argv[2]), atoi(argv[3])); printf("iFinal is %d\n", iFinal); return 0; }来试下:
ubuntu@VM-0-13-ubuntu:~$ ./a.out 220.181.112.244 80 2 iFinal is 0 ubuntu@VM-0-13-ubuntu:~$ ./a.out 220.181.112.244 81 2 iFinal is -3 ubuntu@VM-0-13-ubuntu:~$ ./a.out 220.181.112.244 443 2 iFinal is 0 ubuntu@VM-0-13-ubuntu:~$ ./a.out 220.181.112.244 445 2 iFinal is -3 ubuntu@VM-0-13-ubuntu:~$ ./a.out 1.1.1.1 80 2 iFinal is -3 ubuntu@VM-0-13-ubuntu:~$
批量探测怎么搞呢? 来看看:
#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <malloc.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <stdarg.h> #include <fcntl.h> #include <time.h> #include <iostream> #include <fstream> using namespace std; int telnetCheckTcp(const char *ip, int port, int tSecond) { int sockClient = socket(AF_INET, SOCK_STREAM, 0); int iFinal = 0; struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr(ip); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(port); fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); // 返回-1不一定是异常 if (iRet != 0) { if(errno != EINPROGRESS) { iFinal = -1; } else { struct timeval tm = {tSecond, 0}; fd_set wset, rset; FD_ZERO(&wset); FD_ZERO(&rset); FD_SET(sockClient, &wset); FD_SET(sockClient, &rset); int time1 = time(NULL); int n = select(sockClient + 1, &rset, &wset, NULL, &tm); int time2 = time(NULL); if(n < 0) { iFinal = -2; } else if(n == 0) { iFinal = -3; } else if (n == 1) { if(FD_ISSET(sockClient, &wset)) { iFinal = 0; fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); } else { iFinal = -4; } } else { iFinal = -5; } } } close(sockClient); return iFinal; } int main(int argc, char *argv[]) // ./a.out ipfilename port timeout { if(argc != 4) { cout << "error" << endl; return -1; } ifstream in(argv[1]); string filename; string line; unsigned int i = 0; if(in) // 有该文件 { while (getline (in, line)) // line中不包括每行的换行符 { // 这里最好做ip格式判断 i++; int iFinal = telnetCheckTcp(line.c_str(), atoi(argv[2]), atoi(argv[3])); if(iFinal == 0) { printf("iFinal is %d, ip is %s, index is %d\n", iFinal, line.c_str(), i); } else { printf("iFinal is %d, cannot connect to %s, index is %d\n", iFinal, line.c_str(), i); } } } else // 没有该文件 { cout <<"no such file" << endl; } return 0; }结果:
ubuntu@VM-0-13-ubuntu:~$ ./a.out a.txt 443 2 iFinal is 0, ip is 220.181.112.244, index is 1 iFinal is -3, cannot connect to 1.1.1.1, index is 2 ubuntu@VM-0-13-ubuntu:~$ ubuntu@VM-0-13-ubuntu:~$ ubuntu@VM-0-13-ubuntu:~$ ./a.out a.txt 80 2 iFinal is 0, ip is 220.181.112.244, index is 1 iFinal is -3, cannot connect to 1.1.1.1, index is 2 ubuntu@VM-0-13-ubuntu:~$ ubuntu@VM-0-13-ubuntu:~$ ubuntu@VM-0-13-ubuntu:~$ ./a.out a.txt 100 2 iFinal is -3, cannot connect to 220.181.112.244, index is 1 iFinal is -3, cannot connect to 1.1.1.1, index is 2 ubuntu@VM-0-13-ubuntu:~$搞定。
相关文章推荐
- 控制connect超时时间(linux版本和Windows版本)
- 超时时间已到。在从池中获取连接之前超时时间已过。
- linux下svn不能连接上windows服务器:SSL handshake failed: SSL 错误:在证书中检测到违规的密钥用法
- Linux检测TCP连接断开的一种简单实现方法
- linux下的redmine无法连接windows下的svn服务器,无法进行版本库配置
- windows 2008上启用防火墙后sqlserver 2005经常出现连接超时的解决办法
- 在Linux系统下检测U盘是否已连接的方法
- 异常详细信息: System.InvalidOperationException: 超时时间已到。在从池中获取连接之前超时时间已过
- Windows下通过Telnet连接Linux主机
- android 判断是否真正连接到internet(通过检测网址,需要时间)
- TCP套接口利用TCP自带的 SO_KEEPALIVE选项实现指定时间检测是否激活状态的方法
- 在从池中获取连接之前超时时间已过,所有池连接都已被使用并已达到最大池大小的问题解决方法
- 超时时间已到。在从池中获取连接之前超时时间已过。出现这种情况可能是因为所有池连接都已被使用并已达到最大池大小
- java测试网络连接是否成功并设置超时时间
- TCP的socket连接示例(linux&windows)
- windwos mobile中,怎么检测gprs是否已连接。?
- linux的TCP超时重传--一次数据断开连接分析
- c# 超时时间已到。在从池中获取连接之前超时时间已过(解决方法)
- 超时时间已到。在从池中获取连接之前超时时间已过,连接池达到最大
- 超时时间已到。在从池中获取连接之前超时时间已过。出现这种情况可能是因为所有池连接都已被使用并已达到最大池大小。