问题
I'm trying to work with the Managed Media Aggregation C# library (http://net7mma.codeplex.com) to handle a RTSP/RTP stream from a Freebox Set top box.
Although the lib works fine with the sample RTSP feed, when working with the feed from my set top box, the RTP listener socket (a simple UDP socket listening every income on a specific port) throws a SocketException : ConnectionReset, and of course no data shows while Receiving (The data shows in Wireshark).
Suppressing E_CONNRESET via the SocketIO trick did not much, still no data coming in the socket.
What would cause such a behavior ?
(I can provide the source or Wireshark traces if necessary)
回答1:
Microsoft explain the true meaning of SIO_UDP_CONNRESET:
SIO_UDP_CONNRESET (opcode setting: 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.
The problem is in fact not connection reset but reachability.
MSDN explain the error WSAECONNRESET:
WSAECONNRESET
The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket; it is no longer usable. On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message.
回答2:
I am the author of net7mma.
I really appreciate your help with trying to resolve this.
There may be a bug in WinSock or another part of the Windows Networking Stack. I would be interested to hear if this happens on Mono Also.
However, based on some conversation with the OP the reason why this seems to be occurring is that Freebox is sending the packets on a port which is not the same as which is indicates it will in the describe request.
I will post a little info about this when I get a chance on my projects page but in the mean time I wanted to ensure people searching about this and Freebox get the best info possible.
In RtpClient -> RecieveData
Change :
received = socket.Receive(m_Buffer, received, Math.Min(socket.Available, m_Buffer.Length), SocketFlags.None, out error);
to
var tc = GetContextBySocketHandle(socket.Handle);
EndPoint fbRtp = new IPEndPoint(tc.RemoteRtp.Address, 0);//Any port
received = socket.ReceiveFrom(m_Buffer, SocketFlags.None, ref fbRtp);
This should allow your socket to receive on any port since the stb doesn't correctly report the rtp or rtcp ports, be careful if you have more then 1 client and you decide to use this code as you could unintentionally receive packets from another stream or even if you are just using a single client the Rtcp port of the same stream may unintentionally sneak packets in this receive.
The best course of action if this works is to derive from the RtspClient and the RtpClient and make a FreeboxRtspClient and FreeboxRtpClient which can handle this gracefully.
If someone can find a rhyme to the reason why the box is sending packets on a different port I would be glad to make changes in the current implementation so no derivation is required.
Attached here : http://net7mma.codeplex.com/workitem/16024
You can find the Pcap capture which shows the whole conversation.
-Jay
来源:https://stackoverflow.com/questions/15228272/what-would-cause-a-connectionreset-on-an-udp-socket