int SocketConnectTimeout(char *ip, int iport, int isec)
{
    struct sockaddr_in  dstAddr;
    int                 status;
    int                 flag;
    int                 len = 0;
    int                 fd  = -1;
    int                 sockOpt=1;
    int                 reUseOpt=1;
    fd_set              rSet;
    fd_set              wSet;
struct timeval tv;
if(ip == NULL || iport <= 0 || isec <= 0) {
fprintf(stderr, "invalid ip or invalid iport or invalid timeout(%s,%d,%d)\n", ip, iport, isec); fflush(stderr);
return -1;
}
    dstAddr.sin_family = AF_INET;
    dstAddr.sin_port   = htons(iport);
    dstAddr.sin_addr.s_addr = inet_addr(ip);
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "socket create fail\n"); fflush(stderr);
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&sockOpt, sizeof(sockOpt)) < 0) {
        fprintf(stderr, "setsockopt(SO_KEEPALIVE) fail. errno=%d(%s)\n", errno,strerror(errno));
        close(fd);
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&reUseOpt, sizeof(reUseOpt)) < 0) {
        fprintf(stderr, "setsockopt(SO_REUSEADDR) fail. errno=%d(%s)\n", errno,strerror(errno));
        close(fd);
return -1;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char*)&reUseOpt, sizeof(reUseOpt)) < 0) {
        fprintf(stderr, "setsockopt(SO_REUSEPORT) fail. errno=%d(%s)\n", errno,strerror(errno));
        close(fd);
return -1;
}
struct linger solinger = { 1, 0 };
if(setsockopt(fd, SOL_SOCKET, SO_LINGER, &solinger, sizeof(struct linger)) < 0) {
        fprintf(stderr, "setsockopt (SO_LINGER) fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
        close(fd);
return -1;
}
if((flag = fcntl(fd, F_GETFL, 0)) < 0) {
        fprintf(stderr, "fcntl get fd fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
        close(fd);
return -1;
}
if(fcntl(fd, F_SETFL, flag|O_NONBLOCK) < 0) {
        fprintf(stderr, "fcntl nonblock fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
        close(fd);
return -1;
}
status = connect(fd, (struct sockaddr *)&dstAddr, sizeof(dstAddr));
if((status < 0) && (errno != EINPROGRESS)) {
        fprintf(stderr, "connect fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
        close(fd);
return -1;
    }
    else if(status == 0) {
if(fcntl(fd, F_SETFL, flag) < 0) {
            fprintf(stderr, "fcntl block fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
            close(fd);
return -1;
        }
        else {
return fd;
}
    }
    else {
        FD_ZERO(&rSet);
        FD_SET(fd, &rSet);
wSet = rSet;
        tv.tv_sec  = isec;
        tv.tv_usec = 0;
if(select(fd+1, &rSet, &wSet, NULL, &tv) == 0) {
            fprintf(stderr, "socket connect timeout. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
            close(fd);
return -1;
}
if(FD_ISSET(fd, &rSet) || FD_ISSET(fd, &wSet)) {
int error = 0;
len = sizeof(error);
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
                fprintf(stderr, "getsockopt fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
                close(fd);
                return -1;
            }
if(error) {
                fprintf(stderr, "connect fail getsockopt fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
                close(fd);
return -1;
}
        }
        else {
            fprintf(stderr, "select error. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
            close(fd);
return -1;
}
if(fcntl(fd, F_SETFL, flag) < 0) {
            fprintf(stderr, "fcntl block fail. errno=%d(%s)\n", errno,strerror(errno));  fflush(stderr);
            close(fd);
return -1;
        }
        else {
return fd;
}
}
}


