帶超時時間的telnet該怎麼玩?------檢測tcp是否可連線時經常用到(本文僅給出linux版本,之前部落格也有Windows版本的)
前面說過, 利用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:~$
搞定。
相關文章
- [譯] 時間順序的價格異常檢測
- PostgreSQL 連線 超時異常SQL
- JS 檢測當前時間是否為夏令時JS
- JS實現檢查給定時間範圍是否在每天的某個時間段內JS
- Web 應用實時版本檢測,這麼做最方便Web
- windows10時間同步出錯怎麼辦Windows
- ssh連線超時的解決
- context裡的超時時間是怎麼在微服務之間傳遞的Context微服務
- 50、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?synchronized
- 歷時三天,完成了Flutter版本的玩安卓Flutter安卓
- Oracle 各版本支援時間表Oracle
- 遊戲系統時間重新整理該怎麼測試遊戲
- Linux刪除指定時間之前的檔案Linux
- 時間線測試
- session超時時間的設定Session
- 延長可回退win10系統版本時間期限的方法Win10
- 關於在執行java連線MongoDB時遇到的連線超時問題JavaMongoDB
- exp 匯出時帶時間格式的檔案設定
- *(轉)超時時間已到。超時時間已到 但是尚未從池中獲取連線。出現這種情況可能是因為所有池連線均在使用 並且達到了最大池大小。
- win10時間線有什麼用_win10時間線怎麼使用Win10
- [譯] 時間序列異常檢測演算法演算法
- QPS過萬,redis大量連線超時怎麼解決?Redis
- 電腦連線使用代理ip顯示超時怎麼辦
- Java傳送郵件必帶超時時間配置Java
- 網路連線總超時?從四層模型上解析網路是怎麼連線的模型
- MySQL各個版本發行時間MySql
- gRPC為什麼使用截止時間而不是超時時間?RPC
- 檢視windows開機時間Windows
- 檢視/修改Linux時區和時間Linux
- Timeout 時間已到。在操作完成之前超時時間已過或伺服器未響應。伺服器
- redis主從超時檢測Redis
- 問題描述 超時時間已到。超時時間已到,但是尚未從池中獲取連線。出現這種情況可能是因為所有池連線均在使用,並且達到了最大池大小
- linux的centos版本修改時間重啟後無效的問題LinuxCentOS
- Win10系統怎麼關閉時間軸/時間線功能Win10
- OPPO Find X上市時間與價格預測 OPPO Find X什麼時候釋出?
- Linux下時間的檢視(轉)Linux
- 面試官:Netty心跳檢測機制是什麼,怎麼自定義檢測間隔時間?面試Netty
- TCP-ip建立連線時3次握手,斷開連線時4次揮手TCP