C# 有这样的RTSP Ping吗?
我目前正在开发一个WinForm应用程序,使用C#中的RTSP协议从IP摄像头流式传输视频。一切都很顺利。该应用程序的部分要求包括检查IP摄像头是否在线的功能 因此,我使用System.Net.NetworkInformation.ping类执行了ping函数来ping IP摄像头。假设相机的RTSP url如下:RTSP://[camera IP]:554/Master0 RTSP/1.0,我只需要提取[camera IP]部分并使用Ping类通过使用其IP查看相机是否在线 最初,它一直工作到出现问题,例如,如果输入的IP可能不是预期的IP摄像机(例如计算机的IP),如果输入的设备的IP在线,ping功能仍将工作C# 有这样的RTSP Ping吗?,c#,winforms,network-programming,rtsp,C#,Winforms,Network Programming,Rtsp,我目前正在开发一个WinForm应用程序,使用C#中的RTSP协议从IP摄像头流式传输视频。一切都很顺利。该应用程序的部分要求包括检查IP摄像头是否在线的功能 因此,我使用System.Net.NetworkInformation.ping类执行了ping函数来ping IP摄像头。假设相机的RTSP url如下:RTSP://[camera IP]:554/Master0 RTSP/1.0,我只需要提取[camera IP]部分并使用Ping类通过使用其IP查看相机是否在线 最初,它一直工作到
我试图搜索类似RTSP ping的东西,但找不到。我希望对此事有任何建议或意见。非常感谢C#中的任何示例。感谢您的关注。您可能希望保持一个没有视频/音频RTP流的helper
RTSP
会话,而不是ICMP
ping,检查套接字连接的良好状态,并定期发送选项
或描述
命令,例如每分钟一次,以查看设备是否响应
有人建议使用GET_参数
代替选项,但这是一种较差的方法<代码>选项是必需的,获取参数
不是必需的。两者都有不同的目的。两者的服务器端执行开销都很小<代码>选项显然是两者中的佼佼者
某些服务器可能不支持设置流参数,因此不支持GET_参数和SET_参数
关于C#中的RTSP,请参见此线程
关于平。。。您可以实现如下描述的操作。。。但注意不要使其过于频繁,设备应受到影响
选项
可能有效,但标准规定正确的方法是使用GET\u参数
RFC2326清楚地概述了这一点
10.8获取参数
GET_参数请求检索
URI中指定的表示或流。答复的内容
而响应则留给实现。获取不带
实体主体可用于测试客户端或服务器活动性(“ping”)
虽然服务器可能不支持GET\u参数
,但无法判断服务器将如何响应选项
请求,该请求甚至不需要会话ID。因此,不能保证它将保持现有会话的活动状态
这一点在阅读关于选项
请求的相同RFC时可以清楚地看到
10.1选择
该行为等同于[H9.2]中所述的行为。选择权
请求可以在任何时候发出,例如,如果客户即将
尝试一个非标准的请求。它不影响服务器状态
例如:
C->S: OPTIONS * RTSP/1.0
CSeq: 1
Require: implicit-play
Proxy-Require: gzipped-messages
S->C: RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE
请注意,这些都是虚构的特征(人们希望如此)
我们不会故意忽略一个真正有用的特性
因此,我们可以在本节中有一个强有力的例子)
如果GET_参数不受支持,那么您将使用要保持活动状态的会话的SessionId发出播放请求
即使选项不符合会话ID,并且如果您已经在玩,也不会产生任何不利影响,这也应该有效
有关C#RtspClient的信息,请参见我的项目@
关于CodeProject@的文章,您可以使用并执行以下操作:
public static async Task TestRTSPConnection(string rtspAddress, string user, string password)
{
var serverUri = new Uri(rtspAddress);
var credentials = new NetworkCredential(user, password);
var connectionParameters = new ConnectionParameters(serverUri, credentials);
var cancellationTokenSource = new CancellationTokenSource();
var connectTask = ConnectAsync(connectionParameters, cancellationTokenSource.Token);
if (await Task.WhenAny(connectTask, Task.Delay(15000 /*timeout*/)) == connectTask)
{
if (!connectTask.Result)
{
logger.Warn("Connection refused - check username and password");
}
logger.Info("Connection test completed");
}
else
{
logger.Warn("Connection timed out - check username and password");
}
}
private static async Task<bool> ConnectAsync(ConnectionParameters connectionParameters, CancellationToken token)
{
try
{
using (var rtspClient = new RtspClient(connectionParameters))
{
rtspClient.FrameReceived +=
(sender, frame) => logger.Info($"New frame {frame.Timestamp}: {frame.GetType().Name}");
while (true)
{
logger.Info("Connecting...");
try
{
await rtspClient.ConnectAsync(token);
}
catch (OperationCanceledException)
{
logger.Info("Finishing test before connection could be established. Check credentials");
return false;
}
catch (RtspClientException e)
{
logger.Error($"{e.Message}: {e.InnerException?.Message}");
return false;
}
logger.Info("Connected - camera is online");
return true;
}
}
}
catch (OperationCanceledException)
{
return false;
}
}
公共静态异步任务TestRTSPConnection(字符串rtspAddress、字符串用户、字符串密码)
{
var serverUri=新的Uri(rtspAddress);
var凭证=新的网络凭证(用户、密码);
var connectionParameters=新的connectionParameters(serverUri,凭证);
var cancellationTokenSource=新的cancellationTokenSource();
var connectTask=ConnectAsync(connectionParameters,cancellationTokenSource.Token);
if(wait Task.wheny(connectTask,Task.Delay(15000/*timeout*/)==connectTask)
{
如果(!connectTask.Result)
{
logger.Warn(“连接被拒绝-检查用户名和密码”);
}
logger.Info(“连接测试完成”);
}
其他的
{
logger.Warn(“连接超时-检查用户名和密码”);
}
}
专用静态异步任务ConnectAsync(ConnectionParameters ConnectionParameters,CancellationToken令牌)
{
尝试
{
使用(var rtspClient=new rtspClient(connectionParameters))
{
rtspClient.FrameReceived+=
(sender,frame)=>logger.Info($“新帧{frame.Timestamp}:{frame.GetType().Name}”);
while(true)
{
logger.Info(“连接…”);
尝试
{
等待rtspClient.ConnectAsync(令牌);
}
捕获(操作取消异常)
{
Info(“在建立连接之前完成测试。检查凭据”);
返回false;
}
捕获(RtspClientException e)
{
logger.Error($“{e.Message}:{e.InnerException?.Message}”);
返回false;
}
logger.Info(“已连接-摄像头处于联机状态”);
返回true;
}
}
}
捕获(操作取消异常)
{
返回false;
}
}
如果你只关心pin的话,这对我很有用