Example #1
0
 private void RTSPMessageReceived(RTSPConnection rtspConnection, IPEndPoint remoteEndPoint, byte[] buffer)
 {
     if (RTSPClientMessageReceived != null)
     {
         RTSPClientMessageReceived(rtspConnection, remoteEndPoint, buffer);
     }
 }
Example #2
0
 private void EndSend(IAsyncResult ar)
 {
     try
     {
         RTSPConnection rtspConnection = (RTSPConnection)ar.AsyncState;
         rtspConnection.Stream.EndWrite(ar);
     }
     catch (Exception excp)
     {
         logger.Error("Exception RTSPServer EndSend. " + excp.Message);
     }
 }
Example #3
0
        /// <summary>
        /// Sends data to the RTSP client listening on the destination end point.
        /// </summary>
        /// <param name="destinationEndPoint">The destination to send the message to.</param>
        /// <param name="buffer">The data to send.</param>
        public void Send(IPEndPoint dstEndPoint, byte[] buffer)
        {
            try
            {
                if (buffer == null)
                {
                    throw new ApplicationException("An empty buffer was specified to Send in SIPTCPChannel.");
                }
                else if (m_localIPEndPoint.ToString() == dstEndPoint.ToString())
                {
                    logger.Error("The RTSPServer blocked Send to " + dstEndPoint.ToString() + " as it was identified as a locally hosted TCP socket.\r\n" + Encoding.UTF8.GetString(buffer));
                    throw new ApplicationException("A Send call was made in RTSPServer to send to another local TCP socket.");
                }
                else
                {
                    // Lookup a client socket that is connected to the destination.
                    if (m_connectedSockets.ContainsKey(dstEndPoint.ToString()))
                    {
                        RTSPConnection rtspClientConnection = m_connectedSockets[dstEndPoint.ToString()];

                        try
                        {
                            rtspClientConnection.Stream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(EndSend), rtspClientConnection);
                            rtspClientConnection.LastTransmission = DateTime.Now;
                        }
                        catch (SocketException)
                        {
                            logger.Warn("RTSPServer could not send to TCP socket " + dstEndPoint + ", closing and removing.");
                            rtspClientConnection.Stream.Close();
                            m_connectedSockets.Remove(dstEndPoint.ToString());
                        }
                    }
                    else
                    {
                        logger.Warn("Could not send RTSP packet to TCP " + dstEndPoint + " as there was no current connection to the client, dropping message.");
                    }
                }
            }
            catch (ApplicationException appExcp)
            {
                logger.Warn("ApplicationException RTSPServer Send (sendto=>" + dstEndPoint + "). " + appExcp.Message);
                throw;
            }
            catch (Exception excp)
            {
                logger.Error("Exception (" + excp.GetType().ToString() + ") RTSPServer Send (sendto=>" + dstEndPoint + "). " + excp.Message);
                throw;
            }
        }
Example #4
0
        private void AcceptConnections(string threadName)
        {
            try
            {
                Thread.CurrentThread.Name = threadName;

                logger.Debug("RTSP server socket on " + m_localIPEndPoint + " accept connections thread started.");

                while (!Closed)
                {
                    try
                    {
                        TcpClient tcpClient = m_tcpServerListener.AcceptTcpClient();

                        tcpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

                        IPEndPoint remoteEndPoint = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
                        logger.Debug("RTSP server accepted connection from " + remoteEndPoint + ".");

                        RTSPConnection rtspClientConnection = new RTSPConnection(this, tcpClient.GetStream(), remoteEndPoint);

                        lock (m_connectedSockets)
                        {
                            m_connectedSockets.Add(remoteEndPoint.ToString(), rtspClientConnection);
                        }

                        rtspClientConnection.RTSPSocketDisconnected += RTSPClientDisconnected;
                        rtspClientConnection.RTSPMessageReceived    += RTSPMessageReceived;

                        rtspClientConnection.Stream.BeginRead(rtspClientConnection.SocketBuffer, 0, MaxMessageSize, new AsyncCallback(ReceiveCallback), rtspClientConnection);
                    }
                    catch (Exception acceptExcp)
                    {
                        // This exception gets thrown if the remote end disconnects during the socket accept.
                        logger.Warn("Exception RTSPServer  accepting socket (" + acceptExcp.GetType() + "). " + acceptExcp.Message);
                    }
                }

                logger.Debug("RTSP server socket on " + m_localIPEndPoint + " listening halted.");
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTSPServer Listen. " + excp.Message);
            }
        }
Example #5
0
        private void ReceiveCallback(IAsyncResult ar)
        {
            RTSPConnection rtspConnection = (RTSPConnection)ar.AsyncState;

            try
            {
                int bytesRead = rtspConnection.Stream.EndRead(ar);
                if (rtspConnection.SocketReadCompleted(bytesRead))
                {
                    rtspConnection.Stream.BeginRead(rtspConnection.SocketBuffer, rtspConnection.SocketBufferEndPosition, MaxMessageSize - rtspConnection.SocketBufferEndPosition, new AsyncCallback(ReceiveCallback), rtspConnection);
                }
            }
            catch (SocketException)  // Occurs if the remote end gets disconnected.
            { }
            catch (Exception excp)
            {
                logger.Warn("Exception RTSPServer ReceiveCallback. " + excp.Message);
                RTSPClientSocketDisconnected(rtspConnection.RemoteEndPoint);
            }
        }
Example #6
0
        /// <summary>
        /// Periodically checks the established connections and closes any that have not had a transmission for a specified
        /// period or where the number of connections allowed per IP address has been exceeded.
        /// </summary>
        private void PruneConnections(string threadName)
        {
            try
            {
                Thread.CurrentThread.Name = threadName;

                Thread.Sleep(INITIALPRUNE_CONNECTIONS_DELAY);

                while (!Closed)
                {
                    // Check the TCP connections established by RTSP clients for any inactive ones.
                    try
                    {
                        RTSPConnection inactiveConnection = null;

                        lock (m_connectedSockets)
                        {
                            var inactiveConnectionQuery = from connection in m_connectedSockets
                                                          where connection.Value.LastTransmission < DateTime.Now.AddMinutes(PRUNE_NOTRANSMISSION_MINUTES * -1)
                                                          select connection.Key;

                            var inactiveConnectionKey = inactiveConnectionQuery.FirstOrDefault();

                            while (inactiveConnectionKey != null)
                            {
                                if (inactiveConnectionKey != null)
                                {
                                    inactiveConnection = m_connectedSockets[inactiveConnectionKey];
                                    m_connectedSockets.Remove(inactiveConnectionKey);

                                    logger.Debug("Pruning inactive RTSP connection on to remote end point " + inactiveConnection.RemoteEndPoint + ".");
                                    inactiveConnection.Close();
                                }

                                inactiveConnectionKey = inactiveConnectionQuery.FirstOrDefault();
                            }
                        }
                    }
                    catch (SocketException)
                    {
                        // Will be thrown if the socket is already closed.
                    }
                    catch (Exception pruneExcp)
                    {
                        logger.Error("Exception RTSPServer PruneConnections (pruning). " + pruneExcp.Message);
                    }

                    // Check the list of active RTSP sessions for any that have stopped communicating or that have closed.
                    try
                    {
                        RTSPSession inactiveSession = null;

                        lock (m_rtspSessions)
                        {
                            var inactiveSessionQuery = from session in m_rtspSessions
                                                       where (session.Value.DontTimeout == false &&
                                                              session.Value.RTPLastActivityAt < DateTime.Now.AddSeconds(CLOSE_RTSP_SESSION_NO_DATA_SECONDS * -1) &&
                                                              session.Value.ControlLastActivityAt < DateTime.Now.AddSeconds(CLOSE_RTSP_SESSION_NO_DATA_SECONDS * -1) &&
                                                              session.Value.StartedAt < DateTime.Now.AddSeconds(CLOSE_RTSP_SESSION_NO_DATA_SECONDS * -1) &&
                                                              session.Value.CreatedAt < DateTime.Now.AddSeconds(CLOSE_RTSP_SESSION_NO_DATA_SECONDS * -1)) ||
                                                       session.Value.IsClosed
                                                       select session.Key;

                            var inactiveSessionKey = inactiveSessionQuery.FirstOrDefault();

                            while (inactiveSessionKey != null)
                            {
                                inactiveSession = m_rtspSessions[inactiveSessionKey];
                                m_rtspSessions.Remove(inactiveSessionKey);

                                if (!inactiveSession.IsClosed)
                                {
                                    logger.Debug("Closing inactive RTSP session for session ID " + inactiveSession.SessionID + " established from RTSP client on " + inactiveSession.RemoteEndPoint + " (started at " + inactiveSession.StartedAt + ", RTP last activity at " + inactiveSession.RTPLastActivityAt + ", control last activity at " + inactiveSession.ControlLastActivityAt + ", is closed " + inactiveSession.IsClosed + ").");
                                    inactiveSession.Close();
                                }

                                inactiveSessionKey = inactiveSessionQuery.FirstOrDefault();
                            }
                        }
                    }
                    catch (Exception rtspSessExcp)
                    {
                        logger.Error("Exception RTSPServer checking for inactive RTSP sessions. " + rtspSessExcp);
                    }

                    Thread.Sleep(PRUNE_CONNECTIONS_INTERVAL * 1000);
                }

                logger.Debug("RTSPServer socket on " + m_localIPEndPoint.ToString() + " pruning connections halted.");
            }
            catch (Exception excp)
            {
                logger.Error("Exception RTSPServer PruneConnections. " + excp.Message);
            }
        }