我已经在本机代码中编写客户端套接字程序并在android应用程序中使用它。当服务器不可用时,我在与服务器建立连接时遇到一个奇怪的问题。
当服务器不可用时,客户端connect()调用将进行折腾,它根本不会出现。我试图在互联网上搜索这个。一些链接正在解释这些步骤
我尝试了这些步骤,但无论服务器是否正在运行,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()调用超时时出错的地方..
赞赏任何建议或替代方法。
谢谢。答案 0 :(得分:0)
对于处于非阻塞模式的情况,我看不到您在哪里等待连接完成。
另外,我会问在应用程序建立之前应用程序是否应该执行其他操作?如果是这样,我会考虑使用类似pthreads的东西将SocketConnect函数重组为一个单独的线程。如果您的应用程序的行为完全取决于客户端连接,我会考虑在连接之前将套接字从非阻塞切换到阻塞,并保持呼叫在SocketConnect中连接。
答案 1 :(得分:0)
使用闹钟中断连接。这是示例代码
#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
}
}