Dear Sir:<br><br>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.<br>
<br>Boolean makeSocketBlocking(int sock) {<br>#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)<br>&nbsp; unsigned long arg = 0;<br>&nbsp; return ioctlsocket(sock, FIONBIO, &amp;arg) == 0;<br>#elif defined(VXWORKS)<br>&nbsp; int arg = 1;<br>
&nbsp; return ioctl(sock, FIONBIO, (int)&amp;arg) == 0;<br>#else<br>&nbsp; int curFlags = fcntl(sock, F_GETFL, 0);<br>&nbsp; return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) &gt;= 0;<br>#endif<br>}<br><br>int connect(SOCKET sock, const sockaddr *name, int namelen, int timeout)<br>
{<br>&nbsp;&nbsp; &nbsp;if(!makeSocketNonBlocking(sock))<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(&quot;[connect()] fail to set socket non-blocking\n&quot;);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return -1;<br>&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp; &nbsp;struct timeval tv;<br>&nbsp;&nbsp; &nbsp;tv.tv_sec = timeout;<br>
&nbsp;&nbsp; &nbsp;tv.tv_usec = 0;<br>&nbsp;&nbsp; &nbsp;fd_set rfds, wfds;<br>&nbsp;&nbsp; &nbsp;FD_ZERO(&amp;rfds);<br>&nbsp;&nbsp; &nbsp;int ret = connect(sock, name, namelen);<br><br>&nbsp;&nbsp; &nbsp;do<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(ret == SOCKET_ERROR)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>#if defined(__WIN32__) || defined(_WIN32) || defined(IMN_PIM)<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(WSAGetLastError() != WSAEWOULDBLOCK)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fprintf(stderr, &quot;[connect()] WSAGetLastError()  %d\n&quot;, WSAGetLastError());<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = -1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else // need select<br>#endif<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;FD_SET(sock, &amp;rfds);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;wfds = rfds;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = select(sock + 1, &amp;rfds, &amp;wfds, 0, &amp;tv);<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(ret == 0)<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fprintf(stderr, &quot;[connect()] timeout in %ds\n&quot;, timeout);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = -1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(FD_ISSET(sock, &amp;rfds) || FD_ISSET(sock, &amp;wfds))<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int error;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int size = sizeof(error);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if(getsockopt(sock, SOL_SOCKET, SO_ERROR, (char*)&amp;error, &amp;size) != 0 || error != 0)<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fprintf(stderr, &quot;[connect()] getsockopt() error %d\n&quot;, error);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = -1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;fprintf(stderr, &quot;[connect()] unknown error\n&quot;);<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = -1;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;break;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = 0;<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} <br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;else<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = 0;<br>&nbsp;&nbsp; &nbsp;} while(false);<br><br>&nbsp;&nbsp; &nbsp;if(!makeSocketBlocking(sock))<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; fprintf(&quot;[connect()] fail to set socket blocking\n&quot;);<br>
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;ret = -1;<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp; &nbsp;return ret;<br>}