diff --git a/trunk/research/librtmp/srs_detect_rtmp.c b/trunk/research/librtmp/srs_detect_rtmp.c index 67469460b..d565d1f3f 100644 --- a/trunk/research/librtmp/srs_detect_rtmp.c +++ b/trunk/research/librtmp/srs_detect_rtmp.c @@ -88,7 +88,15 @@ int main(int argc, char** argv) exit(-2); } - rtmp = srs_rtmp_create(rtmp_url); + if ((rtmp = srs_rtmp_create(rtmp_url)) == NULL) { + srs_human_trace("create rtmp failed"); + ret = -1; + goto rtmp_destroy; + } + if ((ret = srs_rtmp_set_timeout(rtmp, timeout * 1000, timeout * 1000)) != 0) { + srs_human_trace("set timeout for rtmp failed. errno=%d", ret); + goto rtmp_destroy; + } if ((ret = srs_rtmp_dns_resolve(rtmp)) != 0) { srs_human_trace("dns resolve failed. ret=%d", ret); diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index d81e682a1..a45c1d4d2 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -27,7 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 - #define SOCKET_ETIME ETIME + #define SOCKET_ETIME EWOULDBLOCK #define SOCKET_ECONNRESET ECONNRESET #define SOCKET_ERRNO() errno @@ -160,10 +160,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. return ret; } - void srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us) + int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us) { SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int sec = timeout_us / (1000 * 1000LL); + int microsec = timeout_us / 1000LL % 1000; + + sec = srs_max(0, sec); + microsec = srs_max(0, microsec); + + struct timeval tv = { sec , microsec }; + if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } skt->recv_timeout = timeout_us; + + return ERROR_SUCCESS; } int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx) { @@ -175,10 +188,24 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; return skt->recv_bytes; } - void srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us) + int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us) { SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int sec = timeout_us / (1000 * 1000LL); + int microsec = timeout_us / 1000LL % 1000; + + sec = srs_max(0, sec); + microsec = srs_max(0, microsec); + + struct timeval tv = { sec , microsec }; + if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } + skt->send_timeout = timeout_us; + + return ERROR_SUCCESS; } int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx) { diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 2c054f788..940905c06 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -484,14 +484,6 @@ int srs_librtmp_context_resolve_host(Context* context) { int ret = ERROR_SUCCESS; - // create socket - srs_freep(context->skt); - context->skt = new SimpleSocketStream(); - - if ((ret = context->skt->create_socket()) != ERROR_SUCCESS) { - return ret; - } - // connect to server:port context->ip = srs_dns_resolve(context->host); if (context->ip.empty()) { @@ -540,6 +532,17 @@ srs_rtmp_t srs_rtmp_create(const char* url) { Context* context = new Context(); context->url = url; + + // create socket + srs_freep(context->skt); + context->skt = new SimpleSocketStream(); + + if (context->skt->create_socket() != ERROR_SUCCESS) { + // free the context and return NULL + srs_freep(context); + return NULL; + } + return context; } @@ -552,8 +555,34 @@ srs_rtmp_t srs_rtmp_create2(const char* url) // auto append stream. context->url += "/livestream"; + // create socket + srs_freep(context->skt); + context->skt = new SimpleSocketStream(); + + if (context->skt->create_socket() != ERROR_SUCCESS) { + // free the context and return NULL + srs_freep(context); + return NULL; + } + return context; } + +int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms) +{ + int ret = ERROR_SUCCESS; + + if (!rtmp) { + return ret; + } + + Context* context = (Context*)rtmp; + + context->skt->set_recv_timeout(recv_timeout_ms * 1000LL); + context->skt->set_send_timeout(send_timeout_ms * 1000LL); + + return ret; +} void srs_rtmp_destroy(srs_rtmp_t rtmp) { diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 5bf16b062..8bf563c50 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -107,6 +107,14 @@ extern srs_rtmp_t srs_rtmp_create(const char* url); * @return a rtmp handler, or NULL if error occured. */ extern srs_rtmp_t srs_rtmp_create2(const char* url); +/** + * set socket timeout + * @param recv_timeout_ms the timeout for receiving messages in ms. + * @param send_timeout_ms the timeout for sending message in ms. + * + * @return 0, success; otherswise, failed. + */ +extern int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms); /** * close and destroy the rtmp stack. * @remark, user should never use the rtmp again. @@ -982,7 +990,7 @@ typedef void* srs_hijack_io_t; * set the socket recv timeout. * @return 0, success; otherswise, failed. */ - extern void srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us); + extern int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us); /** * get the socket recv timeout. * @return 0, success; otherswise, failed. @@ -997,7 +1005,7 @@ typedef void* srs_hijack_io_t; * set the socket send timeout. * @return 0, success; otherswise, failed. */ - extern void srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us); + extern int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us); /** * get the socket send timeout. * @return 0, success; otherswise, failed.