[Live-devel] Consider TCP connection with timeout in RTSPClient::describeURL().

Brain Lai brainlai at gmail.com
Fri Feb 29 22:40:29 PST 2008


Dear Sir:

connect() in RTSPClient::openConnectionFromURL() is blocking. A practical
application may not accept such a behavior. The following functions provide
connect() with timeout setting on Windows(maybe work on Linux). Not very
elegant but work. Please take them into consideration.

Boolean makeSocketBlocking(int sock) {
#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)
  unsigned long arg = 0;
  return ioctlsocket(sock, FIONBIO, &arg) == 0;
#elif defined(VXWORKS)
  int arg = 1;
  return ioctl(sock, FIONBIO, (int)&arg) == 0;
#else
  int curFlags = fcntl(sock, F_GETFL, 0);
  return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0;
#endif
}

int connect(SOCKET sock, const sockaddr *name, int namelen, int timeout)
{
    if(!makeSocketNonBlocking(sock))
    {
        fprintf("[connect()] fail to set socket non-blocking\n");
        return -1;
    }

    struct timeval tv;
    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    fd_set rfds, wfds;
    FD_ZERO(&rfds);
    int ret = connect(sock, name, namelen);

    do
    {
        if(ret == SOCKET_ERROR)
        {
#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)
            if(WSAGetLastError() != WSAEWOULDBLOCK)
            {
                fprintf(stderr, "[connect()] WSAGetLastError() %d\n",
WSAGetLastError());
                ret = -1;
                break;
            }
            else // need select
#endif
            {
                FD_SET(sock, &rfds);
                wfds = rfds;
                ret = select(sock + 1, &rfds, &wfds, 0, &tv);
                if(ret == 0)
                {
                    fprintf(stderr, "[connect()] timeout in %ds\n",
timeout);
                    ret = -1;
                    break;
                }

                if(FD_ISSET(sock, &rfds) || FD_ISSET(sock, &wfds))
                {
                    int error;
                    int size = sizeof(error);
                    if(getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&error,
&size) != 0 || error != 0)
                    {
                        fprintf(stderr, "[connect()] getsockopt() error
%d\n", error);
                        ret = -1;
                        break;
                    }
                }
                else
                {
                    fprintf(stderr, "[connect()] unknown error\n");
                    ret = -1;
                    break;
                }
            }
            ret = 0;
        }
        else
            ret = 0;
    } while(false);

    if(!makeSocketBlocking(sock))
    {
        fprintf("[connect()] fail to set socket blocking\n");
        ret = -1;
    }
    return ret;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.live555.com/pipermail/live-devel/attachments/20080229/18d145e7/attachment.html 


More information about the live-devel mailing list