C 无法设置套接字连接()调用的超时
我已经用本机代码编写了客户端套接字程序,并在android应用程序中使用它。当服务器不可用时,我在连接服务器时面临一个奇怪的问题 当服务器不可用时,客户端connect()调用将被抛出,根本不会出现。我试着在网上搜索这个。一些链接正在解释这些步骤C 无法设置套接字连接()调用的超时,c,sockets,connection,C,Sockets,Connection,我已经用本机代码编写了客户端套接字程序,并在android应用程序中使用它。当服务器不可用时,我在连接服务器时面临一个奇怪的问题 当服务器不可用时,客户端connect()调用将被抛出,根本不会出现。我试着在网上搜索这个。一些链接正在解释这些步骤 将套接字设置为非块模式 调用连接-如果连接成功,则可以 否则,将套接字设置回块模式 为write set设置套接字,并在需要超时的情况下将其指定给select() 如果select输出时在写集中设置了套接字,则连接成功或连接失败 我尝试了这些步骤,但无
bool SocketConnect()
{
... Creating the socket ....
int opts;
if( (opts = fcntl(clientsocket,F_GETFL) < 0 )
{
return false;
}
// setting socket to non-block mode
if( fcntl(clientsocket,opts | O_NONBLOCK) < 0 )
{
return false;
}
//calling connect
int ret = connect(clientsocket,(const sockaddr*)&serveraddr,sizeof(serveraddr));
if( ret < 0 )
{
if( errno != EINPROGRESS )
{
return false;
}
}
if( ret == 0 )
{
//connection successful set the socket to block mode
fcntl(clientsocket,F_SETFL,opts);
return true;
}
//set the socket to block mode
if( fcntl(clientsocket,F_SETFL,opts) < 0 )
{
return false;
}
fd_set writeset;
FD_ZERO(&writeset);
FD_SET(clientsocket,&writeset);
timeval val.
val.tv_sec = 5;
val.tv_usec = 0;
int sret = select(clientsocket+1,NULL,&writeset,NULL,&val);
if( sret > 0 )
{
if( FD_ISSET(clientsocket,&writeset) )
{
fcntl(clientsocket,F_SETFL,opts);
return true;
}
}
return false;
}
bool SocketConnect()
{
…正在创建套接字。。。。
int opts;
if((opts=fcntl(clientsocket,F_GETFL)<0)
{
返回false;
}
//将套接字设置为非块模式
if(fcntl(客户端套接字,选择非块)<0)
{
返回false;
}
//呼叫连接
int ret=connect(clientsocket,(const sockaddr*)和serveraddr,sizeof(serveraddr));
如果(ret<0)
{
if(errno!=EINPROGRESS)
{
返回false;
}
}
如果(ret==0)
{
//连接成功将套接字设置为块模式
fcntl(客户端套接字、F_SETFL、opts);
返回true;
}
//将套接字设置为块模式
如果(fcntl(客户端套接字、F_SETFL、opts)<0)
{
返回false;
}
fd_集写集;
FD_ZERO(写入集和写入集);
FD_集(clientsocket和writeset);
蒂梅瓦尔。
val.tv_sec=5;
val.tv_usec=0;
int sret=select(clientsocket+1,NULL,&writeset,NULL,&val);
如果(sret>0)
{
if(FD_ISSET(clientsocket和writeset))
{
fcntl(客户端套接字、F_SETFL、opts);
返回true;
}
}
返回false;
}
当服务器可用时,如果我使用阻塞连接调用(不使用上述任何步骤),建立连接几乎不需要1秒
当服务器可用时,如果我使用上述步骤进行连接,那么如果我给事件5秒的时间连接未建立。事件选择也未等待5秒,立即返回值0
请查看此代码,并让我知道在设置connection()调用的超时时到底哪里出错了
如有任何建议或替代方法,敬请谅解
谢谢。如果您处于非阻塞模式,我看不出您在等待连接完成
另外,我会问,在连接建立之前,应用程序应该做些什么吗?如果是这样,我会考虑使用pPults之类的东西将SockCuffic函数重新配置到一个单独的线程中。如果应用程序的行为仅仅依赖于客户端连接,我会考虑将套接字从N转换为N。在连接之前从阻塞到阻塞,并在SocketConnect中保留连接调用。
使用报警中断连接。下面是示例代码#define CONNECT_TIMEOUT 4
static void AlarmHandler(int sig)
{
sTimeout = 1;
}
.
.
.
signal(SIGALRM, AlarmHandler);
sTimeout = 0;
alarm(CONNECT_TIMEOUT);
if ( connect(sock, (struct sockaddr *) &server, sizeof(server)) )
{
if ( sTimeout ) {
NSLog(@"timeout connecting stream socket"); //If connect will remain blocked for 4 seconds after 4 seconds this condition will be triggered
}
}
我发现connect()上的linux文档完全错了。在非阻塞connect()上发生某些事情时,您不会得到写入事件,而是会得到读取事件——即使这样,我似乎还记得一些没有发出读取事件的极端情况。(请记住,超时的TCP SYNs可能需要几分钟,超时的ARP请求也可能需要几秒钟-在许多情况下,TCP/IP堆栈无法对connect()提供近乎即时的反馈)他在非阻塞模式下调用connect(),这会导致connect()立即返回,并延迟连接完成(或超时)选择()调用Hi感谢您的响应..我用其他方法解决了这个问题。现在我使用setsockopt设置读写操作的超时。现在,如果服务器在超时内没有响应,连接将出现…:-)