参考链接:http://www.cnblogs.com/GameDeveloper/p/3406565.html
注意点: select() 只是执行一次的超时检测。重新进行select要重新设置“超时时间”以及“句柄”。
connect 非阻塞的例子:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h> int main(int argc, char** argv)
{
int sockfd,recvbytes,res,flags,error=-,n;
socklen_t len;
fd_set rset,wset;
struct timeval tval;
struct sockaddr_in serv_addr;
char*sendData="";//发送字符串
char buf[]="/0"; //接收buffer
//创建socket描述符
if((sockfd = socket(AF_INET, SOCK_STREAM, )) == -)
{
perror("socket create failed");
return ;
} serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons();
serv_addr.sin_addr.s_addr=inet_addr("172.16.0.111");
bzero(&(serv_addr.sin_zero),);
flags=fcntl(sockfd,F_GETFL,);
fcntl(sockfd,F_SETFL,flags|O_NONBLOCK);//设置为非阻塞 if( (res = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) )< )
{
if(errno != EINPROGRESS)
{
return ;
} } //如果server与client在同一主机上,有些环境socket设为非阻塞会返回 0
// if(0 == res) goto done; while(error!=){ tval.tv_sec=;
tval.tv_usec=; //要在while重新设置时间,否则超时不生效
FD_ZERO(&rset); //要在while重新添加句柄,否则检测不了变化
FD_SET(sockfd,&rset);
wset=rset;
printf("enter while\n"); res = select(sockfd+, NULL, &wset, NULL,&tval) ;
if( res == )
{
perror("connect time out\n");
// close(sockfd);
// return 1;
}
else
{
if(res>){ len=sizeof(error);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); printf("error:%d\n", error);
if(error)
{
fprintf(stderr, "Error in connection() %d - %s\n", error, strerror(error));
// return 1;
} } }
} if(res !=)
{
printf("done\n");
if( (n = send(sockfd, sendData, strlen(sendData),) ) ==- )
{ perror("send error!");
close(sockfd);
return ;
}
if( ( n = select(sockfd+,&rset,NULL, NULL,&tval)) <= )//rset没有使用过,不用重新置为sockfd
{
perror("receive time out or connect error");
close(sockfd);
return -;
}
if((recvbytes=recv(sockfd, buf, , )) ==-)
{
perror("recv error!");
close(sockfd);
return ;
} printf("receive num %d\n",recvbytes);
printf("%s\n",buf); }
}