我正在尝试使用Managed Media Aggregation C#库(http://net7mma.codeplex.com)来处理来自Freebox机顶盒的RTSP / RTP流。
虽然lib可以正常使用示例RTSP提要,但是当使用来自我的机顶盒的提要时,RTP侦听器套接字(一个简单的UDP套接字侦听特定端口上的每个收入)会抛出SocketException:ConnectionReset,当然接收时没有数据显示 (数据显示在Wireshark中)。
通过SocketIO技巧抑制E_CONNRESET并不多,套接字中仍然没有数据。
会导致这种行为的原因是什么?
(如果需要,我可以提供源或Wireshark跟踪)
答案 0 :(得分:5)
Microsoft explain SIO_UDP_CONNRESET的真正含义:
SIO_UDP_CONNRESET(操作码设置:I,T == 3)
Windows XP: Controls whether UDP PORT_UNREACHABLE messages are reported. - Set to TRUE to enable reporting. - Set to FALSE to disable reporting.
问题实际上是没有重置连接,而是可达性。
MSDN explain错误WSAECONNRESET:
WSAECONNRESET
虚拟电路由远程端执行硬盘或硬盘重置 流产关闭。应用程序应关闭套接字;不是 更长的可用。 在UDP数据报套接字上,此错误表示a 之前的发送操作导致ICMP端口无法访问消息。
答案 1 :(得分:1)
我是net7mma的作者。
我非常感谢您帮助我们解决此问题。
WinSock或Windows网络堆栈的其他部分可能存在错误。我很想知道Mono是否会发生这种情况。
然而,根据与OP的一些对话,似乎发生这种情况的原因是Freebox正在一个端口上发送数据包,该端口与描述请求中的数据不同。
当我在项目页面上获得机会时,我会发布一些关于此的信息,但同时我想确保人们搜索此内容,Freebox可以获得最佳信息。
在RtpClient -> RecieveData
更改:
received = socket.Receive(m_Buffer, received, Math.Min(socket.Available, m_Buffer.Length), SocketFlags.None, out error);
到
var tc = GetContextBySocketHandle(socket.Handle);
EndPoint fbRtp = new IPEndPoint(tc.RemoteRtp.Address, 0);//Any port
received = socket.ReceiveFrom(m_Buffer, SocketFlags.None, ref fbRtp);
这应该允许你的套接字在任何端口上接收,因为stb没有正确报告rtp或rtcp端口,如果你有超过1个客户端并且你决定使用这个代码,你可能会无意中接收来自另一个流,或者即使您只是使用单个客户端,同一个流的Rtcp端口也可能会无意中隐藏此接收中的数据包。
如果这样做的最佳方法是从RtspClient和RtpClient派生并制作一个FreeboxRtspClient和FreeboxRtpClient,它可以优雅地处理它。
如果有人能够找到盒子在不同端口上发送数据包的原因的押韵,我很乐意在当前实现中进行更改,因此不需要派生。
附在此处:http://net7mma.codeplex.com/workitem/16024
您可以找到显示整个会话的Pcap捕获。
-Jay