请问我该怎样可以超时跳出等待,继续执行下面的代码,并提示连接失败?

如果其输入参数中的IP不存在,connect函数就会一直等待。

MYYA
浏览 81回答 2
2回答

慕容708150

多线程

ibeautiful

在使用此函数前,需先将socket设置为非锁定模式,这样,在connect时,才会立马跳过,同时,通常也会产生一个WSAEWOULDBLOCK错误,这个错误没关系。再执行select则是真正的超时。WSADATA wsd;SOCKET cClient;int ret;struct sockaddr_in server;hostent *host=NULL;if(WSAStartup(MAKEWORD(2,0),&wsd)){return 0;}cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(cClient==INVALID_SOCKET){return 0;}//set Recv and Send time outint TimeOut=6000; //设置发送超时6秒if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){return 0;}TimeOut=6000;//设置接收超时6秒if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){return 0;}//设置非阻塞方式连接unsigned long ul = 1;ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul);if(ret==SOCKET_ERROR)return 0;//连接server.sin_family = AF_INET;server.sin_port = htons(25);server.sin_addr .s_addr = inet_addr((LPCSTR)pSmtp);if(server.sin_addr.s_addr == INADDR_NONE){return 0;}connect(cClient,(const struct sockaddr *)&server,sizeof(server));//select 模型,即设置超时struct timeval timeout ;fd_set r;FD_ZERO(&r);FD_SET(cClient, &r);timeout.tv_sec = 15; //连接超时15秒timeout.tv_usec =0;ret = select(0, 0, &r, 0, &timeout);if ( ret <= 0 ){::closesocket(cClient);return 0;}//一般非锁定模式套接比较难控制,可以根据实际情况考虑 再设回阻塞模式unsigned long ul1= 0 ;ret = ioctlsocket(cClient, FIONBIO, (unsigned long*)&ul1);if(ret==SOCKET_ERROR){::closesocket (cClient);return 0;}--------------------------------------------------------------------------------------------------------------LINUX下的方法:在阻塞套接字的一般情况下,connect ()直到客户端对SYN消息的ACK消息到达之前才会返回。使connect()调用具有超时机制的一个方法是让套接字成为非阻塞的套接字体,然后用select()来等待它完成。[code:1:7901c37cf2]s = socket(AF_INET, SOCK_STREAM, 0);//下面获取套接字的标志if ((flags = fcntl(s, F_GETFL, 0)) < 0) {//错误处理}//下面设置套接字为非阻塞if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {//错误处理}if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&&nbsp;errno != EINPROGRESS) {//因为套接字设为NONBLOCK,通常情况下,连接在connect()返回//之前是不会建立的,因此它会返回EINPROGRESS错误,如果返回//任何其他错误,则要进行错误处理}if (0 == retcode) { //如果connect()返回0则连接已建立//下面恢复套接字阻塞状态if (fcntl(s, F_SETFL, flags) < 0) {//错误处理}//下面是连接成功后要执行的代码exit(0)}FD_ZERO(&rdevents);FD_SET(s, &rdevents); //把先前的套接字加到读集合里面wrevents = rdevents; //写集合exevents = rdevents; //异常集合tv.tv_sec = 5; //设置时间为5秒tv_tv_usec = 0;retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);if (retcode < 0) { //select返回错误???//错误处理}else if (0 == retcode) { //select 超时???//超时处理}esle {//套接字已经准备好if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {//connect()失败,进行错处理}if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {//getsockopt()失败,进行错处理}if (err != 0) {//connect()失败,进行错处理}//到这里说明connect()正确返回//下面恢复套接字阻塞状态if (fcntl(s, F_SETFL, flags) < 0) {//错误处理}//下面是连接成功后要执行的代码exit(0)&nbsp;
打开App,查看更多内容
随时随地看视频慕课网APP