直接上代碼:
設置連接超時
//首先改成非阻塞套接字 unsigned long ul=1; int rm=ioctl(sConnect,FIONBIO,(unsigned long*)&ul); if(rm==-1) { printf("ioctl noblock error!\n"); close(sConnect); return -3; } //向服務器發出連接請求 int err = connect(sConnect, (struct sockaddr*)&addrServer, sizeof(addrServer)); //正常返回EINPROGRESS if(err && errno!=EINPROGRESS) { printf("cannot connect:%s\n",severAgent); return -4; } //有可能返回0 if (err==0) { printf("connect suceess!"); } else { struct timeval tv; fd_set /*r,*/w; // FD_ZERO(&r); FD_ZERO(&w); // FD_SET(sConnect,&r); FD_SET(sConnect,&w); tv.tv_sec=m_conTimeout; tv.tv_usec=0; int retval = select(sConnect+1,0,&w,0,&tv); if(retval==-1) { printf("select error\n"); return -5; } else if(retval == 0) { printf("connect timeout\n"); return -6; } else { int er; socklen_t len = sizeof(er); if (getsockopt(sConnect, SOL_SOCKET, SO_ERROR, (char *)&er, &len) < 0) { //getsockopt()失敗,進行錯處理 printf("getsockopt error\n"); return -8; } if (er != 0) { //connect()失敗,進行錯處理 printf("connect error\n"); return -9; } } }
//改為阻塞 ul=0; rm=ioctl(sConnect,FIONBIO,(unsigned long*)&ul); if(rm==-1) { printf("ioctl block error!\n"); close(sConnect); return -7; }
值得注意的是:linux中,如果服務器的地址無效,則以上超時過程正常。如果服務器地址有效,但是服務程序未開啟,則直接返回錯誤,也就是說超時過程不起作用,說明是已經做了目標網絡檢測了。
但是window中,同樣是以上的代碼,如果服務器的地址無效,則以上超時過程正常。如果服務器地址有效,但是服務程序未開,以上超時過程也是正常的。
二者還是有點區別的。