当前位置: 技术问答>linux和unix
tcp connect 连接非阻塞超时连接?
来源: 互联网 发布时间:2017-01-09
本文导语: linux 3.0 内核。。。 我试了下。2.6好像也是吧。。。 首先设置SOCKET为非阻塞。 然后select 来判断超时。。 但是毫无作用,如果连接一个没有的地址会出现 操作中的提示。一直是这个返回。。。怎么回事 查...
linux 3.0 内核。。。
我试了下。2.6好像也是吧。。。
首先设置SOCKET为非阻塞。 然后select 来判断超时。。
但是毫无作用,如果连接一个没有的地址会出现 操作中的提示。一直是这个返回。。。怎么回事
查了下资料说 unix 才这样 linux 没法。。。
你们谁实验成功了?
我试了下。2.6好像也是吧。。。
首先设置SOCKET为非阻塞。 然后select 来判断超时。。
但是毫无作用,如果连接一个没有的地址会出现 操作中的提示。一直是这个返回。。。怎么回事
查了下资料说 unix 才这样 linux 没法。。。
你们谁实验成功了?
|
我想让它失败后多尝试几次重连,发现没效果,你就判断一趟就行了.
connect,返回0直接成功,返回-1且错误是EINPROGRESS则调用select等待,select返回判断如果是正常返回且getsockopt SO_ERROR如果没有出错的话可以认为连接成功,select超时范围则认为连接失败.
其实红色那句话经过测试无论是否连接成功都不会返回错误.
只要连接成功,或者连接失败,select都会几乎立即返回,根本不会停留,所以楼主必须在select里调用点其他的东西,比如getpeername看看是否出错,getsockopt那句是废话,APUE书上写的是错的。
|
非阻塞connect的问题,贴一下你写的代码围观一下.
|
我拿以前些代码改了改,测试了一下,非阻塞connect的代码和测试server我是这么写的,一切正常:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
int clifd=socket(AF_INET,SOCK_STREAM,0);
if(clifd==-1)
{
return 1;
}
int flag;
if(fcntl(clifd,F_GETFL,&flag)==-1)
{
perror("fcntl:GETFL");
return 2;
}
flag|=O_NONBLOCK;
if(fcntl(clifd,F_SETFL,&flag)==-1)
{
perror("fcntl:SETFL");
return 3;
}
fd_set rSet,wSet;
fd_set rrSet,wrSet;
bzero(&rSet,sizeof(fd_set));
bzero(&wSet,sizeof(fd_set));
FD_SET(clifd,&rSet);
FD_SET(clifd,&wSet);
sockaddr_in srvAddr;
srvAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
srvAddr.sin_port=htons(12000);
srvAddr.sin_family=AF_INET;
int times=0;
int sus=0;
while(times++0 )
{
if(FD_ISSET(clifd,&rrSet)||FD_ISSET(clifd,&wrSet))
{
int err=0;
socklen_t len=sizeof(err);
if(getsockopt(clifd,SOL_SOCKET,SO_ERROR,&err,&len)==-1)
{
continue;
}
if(err!=0)
{
continue;
}
sus=1;
break;
}
}
else if(nRet==0)
{
printf("out of timen");
}
else
{
printf("select error");
}
}
if(sus==1)
{
printf("connect after it n");
close(clifd);
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int s;
int status=1;
struct sockaddr_in server;
struct sockaddr_in client;
if( (s=socket(AF_INET,SOCK_STREAM,0))==-1 )
{
perror("socket:");
return 1;
}
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&status,sizeof(status));
bzero(&server,sizeof(server));
server.sin_port=htons(12000);
server.sin_addr.s_addr=inet_addr("127.0.0.1");
server.sin_family=AF_INET;
if( (status=bind(s,(struct sockaddr*)&server,sizeof(struct sockaddr_in)))==-1 )
{
perror("bind");
return 2;
}
if(listen(s,5)==-1)
{
perror("listen");
return 10;
}
char buffer[1024];
socklen_t len=sizeof(struct sockaddr);
size_t n;
int clifd;
while(true)
{
clifd=accept(s,(struct sockaddr*)&client,&len);
printf("accept donen");
if(clifd==-1)
{
perror("accept");
return 12;
}
while(true)
{
n=recv(clifd,buffer,1024,0);
if(n==-1)
{
if(errno!=EINTR)
{
perror("recv:");
return 1;
}
continue;
}
else if(n==0)
{
close(clifd);
break;
}
else
{
buffer[n]=0;
printf("%sn",buffer);
}
}
}
close(s);
return 0;
}
|
struct timeval tv;
tv.tv_sec=5000;
tv.tv_usec=0;
改成:
struct timeval tv;
tv.tv_sec=2;
tv.tv_usec=0;
tv.tv_sec=5000;
tv.tv_usec=0;
改成:
struct timeval tv;
tv.tv_sec=2;
tv.tv_usec=0;