玩树莓派由于没有屏幕,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