C Gstreamer RTSP客户端超时问题
我与Gstreamer的RTSP客户端有一些问题。因此,我有一个客户端程序,我希望它在RTSP客户端接收/发送消息或返回错误等时,通过看门狗功能向我提供正确的响应,并在出现错误时相应地退出代码。所以我要做的是C Gstreamer RTSP客户端超时问题,c,client,gstreamer,rtsp,C,Client,Gstreamer,Rtsp,我与Gstreamer的RTSP客户端有一些问题。因此,我有一个客户端程序,我希望它在RTSP客户端接收/发送消息或返回错误等时,通过看门狗功能向我提供正确的响应,并在出现错误时相应地退出代码。所以我要做的是 我只需在我的机器上使用VLC创建一个RTSP服务器,然后连接到此服务器。显然,我可以成功创建连接 我通过简单地关闭VLC来停止服务器。因此,现在看门狗功能应该接收正确的错误代码并将其打印到屏幕上。但它从来没有这样做过。在Gstreamer的RTSP文档中,有一个名为gst\u RTSP\u
gst\u RTSP\u connection\u connect
的函数,它接受一个连接和一个超时值,并且在文档中指出,如果超时为NULL,该函数可能会永远阻塞。所以我认为,因为我在timeout字段中输入了NULL,它从不超时,并且认为它仍然连接到服务器,因此不会进入任何看门狗函数。但是,当我应用时,比如说5秒超时,它会在5-7秒后直接终止连接,并进入一些看门狗函数。我不希望我的代码立即给出一个错误,即使有一个正确的连接,服务器仍在运行,我只希望它给出一些错误,当服务器实际关闭,一些超时时间已经过去。我怎样才能解决这个问题/*
* INCLUDES
* /usr/include/gstreamer-1.0
* /usr/include/glib-2.0
* /usr/lib/x86_64-linux-gnu/glib-2.0/include
* /usr/include/gstreamer-1.0/gst/rtsp
*
* LIBRARIES
* gstreamer-1.0
* gstrtsp-1.0
* gobject-2.0
* glib-2.0
*
* MISC.
* -std=c99
*
*
*
* */
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp/gstrtspmessage.h>
#include <gst/rtsp/gstrtspurl.h>
#include <gst/rtsp/gstrtspdefs.h>
#include <gst/rtsp/gstrtsptransport.h>
#include <gst/rtsp/gstrtspconnection.h>
#include <stdlib.h>
#include <stdio.h>
#include <glib.h>
static GstRTSPStatusCode
tunnel_start (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_start\n");
return GST_RTSP_STS_OK;
}
static GstRTSPResult
tunnel_complete (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_complete\n");
return GST_RTSP_OK;
}
static GstRTSPResult
tunnel_lost (GstRTSPWatch * watch, gpointer user_data)
{
g_print("tunnel_lost\n");
return GST_RTSP_OK;
}
static GstRTSPResult
closed (GstRTSPWatch * watch, gpointer user_data)
{
g_print("closed\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_sent (GstRTSPWatch * watch, guint id, gpointer user_data)
{
g_print("message_sent\n");
return GST_RTSP_OK;
}
static GstRTSPResult
message_received (GstRTSPWatch *watch, GstRTSPMessage *message, gpointer user_data) {
g_print("message_received\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error (GstRTSPWatch *watch, GstRTSPResult result, gpointer user_data) {
g_print("error\n");
return GST_RTSP_OK;
}
static GstRTSPResult
error_full (GstRTSPWatch *watch, GstRTSPResult result, GstRTSPMessage *message, guint id, gpointer user_data) {
g_print("error_full\n");
return GST_RTSP_OK;
}
static GstRTSPWatchFuncs watch_funcs = {
message_received,
message_sent,
closed,
error,
tunnel_start,
tunnel_complete,
error_full,
tunnel_lost
};
/* main method */
int main (int argc, char *argv[]) {
GMainLoop *loop;
loop = g_main_loop_new (NULL, FALSE);
GstRTSPUrl *url = NULL;
GstRTSPConnection *conn = NULL;
GstRTSPResult res;
GstRTSPWatch *watch;
GTimeVal *timeout;
timeout->tv_sec = 5;
timeout->tv_usec = 5000000;
res = gst_rtsp_url_parse ("rtsp://localhost:5000/test", &url);
res = gst_rtsp_connection_create (url, &conn);
if (res == GST_RTSP_OK) {
g_print("Connection created.\n");
}
res = gst_rtsp_connection_connect (conn, timeout);
if (res == GST_RTSP_OK) {
g_print("Connection connected.\n");
} else {
g_printerr("Connection not connected. Exiting with code 500.\n");
exit(500);
}
watch = gst_rtsp_watch_new (conn, &watch_funcs, loop, NULL);
if (watch == NULL) {
g_print("Failed to create watch.\n");
}
gst_rtsp_watch_attach (watch, NULL);
gst_rtsp_url_free (url);
g_main_loop_run (loop);
return 0;
}
/*
*包括
*/usr/include/gstreamer-1.0
*/usr/include/glib-2.0
*/usr/lib/x86_64-linux-gnu/glib-2.0/include
*/usr/include/gstreamer-1.0/gst/rtsp
*
*图书馆
*gstreamer-1.0
*gstrtsp-1.0
*gobject-2.0
*glib-2.0
*
*杂项。
*-std=c99
*
*
*
* */
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态GSTRTSPStatus代码
隧道启动(GstRTSPWatch*监视,gpointer用户数据)
{
g_打印(“隧道启动”);
返回GST\u RTSP\u STU\u OK;
}
静态GstRTSPResult
隧道完成(GstRTSPWatch*监视,gpointer用户数据)
{
g_print(“隧道_complete\n”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
隧道_丢失(GstRTSPWatch*手表、gpointer用户_数据)
{
g_打印(“隧道丢失”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
关闭(GstRTSPWatch*监视,gpointer用户数据)
{
g_打印(“已关闭”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
已发送消息(GstRTSPWatch*手表、吉尼特id、gpointer用户数据)
{
g_打印(“已发送消息”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
接收到消息(GstRTSPWatch*监视、GstRTSPMessage*消息、gpointer用户数据){
g_打印(“收到的消息”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
错误(GstRTSPWatch*监视、GstRTSPResult结果、gpointer用户数据){
g_打印(“错误”);
返回GST\u RTSP\u OK;
}
静态GstRTSPResult
错误\u已满(GstRTSPWatch*监视、GstRTSPResult结果、GstRTSPMessage*消息、吉尼特id、gpointer用户\u数据){
g_print(“错误_full\n”);
返回GST\u RTSP\u OK;
}
静态GstRTSPWatchFuncs watch_funcs={
收到消息!,
你发出的信息,
关闭
错误,
隧道开始,,
隧道工程完成,,
错误(u full),,
隧道失事
};
/*主要方法*/
int main(int argc,char*argv[]){
GMainLoop*循环;
loop=g_main_loop_new(NULL,FALSE);
GstRTSPUrl*url=NULL;
GSTRTSP连接*conn=NULL;
GstRTSPResult res;
GstRTSPWatch*手表;
GTimeVal*超时;
超时->电视秒=5;
超时->tv\u usec=5000000;
res=gst\u rtsp\u url\u parse(“rtsp://localhost:5000/test“,&url);
res=gst\u rtsp\u连接\u创建(url和连接);
如果(res==GST\U RTSP\U正常){
g_print(“已创建连接。\n”);
}
res=gst\u rtsp\u连接\u连接(连接,超时);
如果(res==GST\U RTSP\U正常){
g_print(“连接已连接。\n”);
}否则{
g_printerr(“连接未连接。以代码500退出。\n”);
出口(500);
}
watch=gst\u rtsp\u watch\u new(连接和监视功能,循环,空);
if(watch==NULL){
g_print(“创建手表失败。\n”);
}
gst_rtsp_watch_attach(手表,空);
gst\u rtsp\u url\u免费(url);
g_主循环运行(循环);
返回0;
}
此代码按预期工作。我做了错误的测试
我“停止”rtsp服务器的方式只是按下VLC的“停止”按钮。这不会破坏服务器,服务器仍然存在,只是没有生成任何类型的流,客户端仍然连接到服务器,没有问题,因为服务器仍然存在。当我关闭VLC而不是销毁服务器时,它进入了正确的看门狗功能。此代码按预期工作。我做了错误的测试 我“停止”rtsp服务器的方式只是按下VLC的“停止”按钮。这不会破坏服务器,服务器仍然存在,只是没有生成任何类型的流,客户端仍然连接到服务器,没有问题,因为服务器仍然存在。当我关闭VLC而不是破坏服务器时,它进入了正确的看门狗功能