windows下帶超時的telnet探測IP和埠
阿新 • • 發佈:2019-02-05
玩樹莓派由於沒有螢幕,IP可能會跳,這時就不知道自己的樹莓派是哪個IP了,下面可以用這個程式去探測自己樹莓派的IP。其主要思想是:非阻塞的帶超時的connect函式。
經測試,可用。#include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") int telnet_test_tcp(char *ip,int port,int timeout) { // 網路初始化 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 2); WSAStartup( wVersionRequested, &wsaData ); // 建立客戶端socket(預設為是阻塞socket) SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); // 設定為非阻塞的socket int iMode = 1; ioctlsocket(sockClient, FIONBIO, (u_long FAR*)&iMode); // 定義服務端 SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr(ip); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(port); // 超時時間 struct timeval tm; tm.tv_sec = timeout; tm.tv_usec = 0; int ret = -1; // 嘗試去連線服務端 if (-1 != connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))) { ret = 1; // 連線成功 } else { //select過程 fd_set wset,rset; FD_ZERO(&wset); FD_ZERO(&rset); FD_SET(sockClient, &wset); FD_SET(sockClient, &rset); int n = select(-1, &rset, &wset, NULL, &tm); if (n < 0) { ret = -1; // select錯誤 } else if(n == 0) { ret = -2;//select超時 } else if(n == 1) { if(FD_ISSET(sockClient,&wset)) { ret = 0; } else { ret = -3; } } else //其他問題 { ret = -4; } } iMode = 0; ioctlsocket(sockClient, FIONBIO, (u_long FAR*)&iMode); //設定為阻塞模式 // connect狀態 if(ret == 0) { printf("%s, %d ---------->ok\n",ip,port); } else { printf("%s, %d error\n",ip,port); } // 釋放網路連線 closesocket(sockClient); WSACleanup(); return 0; } int main() { char ip[20]; int i=1; for(i=1;i<=255;i++) { sprintf(ip,"192.168.1.%d",i); telnet_test_tcp(ip,22,1); } return 0; }
關於select和非阻塞connect的以下2個規則:1)當連線成功建立時,描述符變為可寫 2)當連線遇到錯誤時,描述符變為即可讀又可寫
linux版本可參考:http://blog.csdn.net/stpeace/article/details/78835802