c-无法设置套接字connect()调用的超时



我已经用原生代码编写了客户端套接字程序,并在android应用程序中使用它。当服务器不可用时,我在连接服务器时遇到了一个奇怪的问题。

当服务器不可用时,客户端connect()调用将被抛出,根本不会发出。我试着在网上搜索这个。一些链接解释了这些步骤

  1. 将套接字设置为非阻塞模式
  2. 调用连接-如果连接成功
  3. 否则将套接字设置回块模式
  4. 为write-set设置套接字,并在需要超时的情况下将其交给select()
  5. 如果选择在写入集中带有套接字集,则连接成功或连接失败

我尝试了这些步骤,但无论服务器是否正在运行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;
}

当服务器可用时,如果我使用阻止的连接调用(不使用任何上述步骤),则几乎不需要1秒即可建立连接。

当服务器可用时,如果我使用上面提到的步骤进行连接,那么如果我给5秒时间,则事件连接没有建立。事件选择也没有等待5秒,它的输出立即返回值0。

请检查这段代码,让我知道我在设置connection()调用的超时时到底哪里出了问题。。

任何建议或可供选择的方法都将受到赞赏。

谢谢。

使用报警中断连接。以下是示例代码

#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
}
}

对于处于非阻塞模式的情况,我看不出您在哪里等待连接完成。

此外,我想问一下,在建立连接之前,应用程序是否还应该做其他事情?如果是这样的话,我会考虑使用pthreads之类的东西将SocketConnect函数重组为一个单独的线程。如果你的应用程序的行为仅取决于客户端连接,我会考虑在连接之前将套接字从非阻塞切换为阻塞,并在SocketConnect中保留连接调用。

最新更新