如何处理非阻塞connect的ECONNREFUSED错误?
这是源码:
int create_gw_connection(char *server, int port, int *sock)
{
char chFunc[]="create_gw_connection";
struct hostent *host = NULL;
struct sockaddr_in saddr;
struct timeval tv;
int ret, flags, n;
time_t start;
int error, len;
fd_set writefds;
int sockfd;
char log_buf[MAX_TX_SIZE];
fd_set rset,wset;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
saddr.sin_addr.s_addr = inet_addr( server );
sockfd = 0;
if( (sockfd=socket(AF_INET, SOCK_STREAM, 0))<0)
{
write_log(GATEWAY, llNormal, "create socket error!");
return -1;
}
//non-block
flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
error = 0;
if( (n=connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr))) < 0)
{
if( errno != EINPROGRESS && errno != EINTR )
{
write_log(GATEWAY, llNormal, "connect error!");
if( close( sockfd ) != 0 )
{
//这种错误,经常连不上?
if( errno == ECONNREFUSED )
{
sleep( 5 );
close( sockfd );
}
}
return -1;
}
}
if( n == 0 )goto done;
FD_ZERO( &rset );
FD_SET( sockfd, &rset);
wset = rset;
tv.tv_sec = 5; //wait for 5 seconds
tv.tv_usec = 0;
if( (n=select(sockfd+1, &rset, &wset, NULL, &tv)) == 0 )
{
write_log(GATEWAY, llNormal, "select error!");
close( sockfd );
errno = ETIMEDOUT;
return -1;
}
if( FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset) )
{
len = sizeof( error );
if( getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0 )
{
write_log(GATEWAY, llNormal, "getsocktopt error!");
close( sockfd );
return -1;
}
}
else
{
snprintf(log_buf, sizeof(log_buf), "[%s]select error - sockfd not set", chFunc);
write_log( GATEWAY, llError, log_buf);
close( sockfd );
return -1;
}
done:
if( error )
{
write_log(GATEWAY, llNormal, "error...");
close( sockfd );
errno = error;
return -1;
}
*sock = sockfd;
return 0;
}
(环境是Solaris 8)
在信号处理函数中调用,大部分时候可以正确连接服务器,但有时连接不上,而且反复连不上:
连接建立好之后,停止侦听服务器几分钟,再启动服务器,有些客户端调用这个函数报告Connection Refused错误,死活连不上。
有谁知道怎么回事吗?怎样才能解决这个问题?