Beispiel #1
0
 private void RTSPMessageReceived(RTSPConnection rtspConnection, IPEndPoint remoteEndPoint, byte[] buffer)
 {
     if (RTSPClientMessageReceived != null)
     {
         RTSPClientMessageReceived(rtspConnection, remoteEndPoint, buffer);
     }
 }
        /// <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.Logger.Error("The RTSPServer blocked Send to " + dstEndPoint.ToString() +
                                        " as it was identified as a locally hosted TCP socket.->" +
                                        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.Logger.Error("RTSPServer could not send to TCP socket " + dstEndPoint +
                                                ", closing and removing.");
                            rtspClientConnection.Stream.Close();
                            m_connectedSockets.Remove(dstEndPoint.ToString());
                        }
                    }
                    else
                    {
                        Logger.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.Logger.Error("ApplicationException RTSPServer Send (sendto=>" + dstEndPoint + "). ->" +
                                    appExcp.Message);
                throw;
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception (" + excp.GetType().ToString() + ") RTSPServer Send (sendto=>" +
                                    dstEndPoint +
                                    "). ->" + excp.Message);
                throw;
            }
        }
Beispiel #3
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);
     }
 }
        private void AcceptConnections(string threadName)
        {
            try
            {
                Thread.CurrentThread.Name = threadName;

                Logger.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.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.Logger.Error("Exception RTSPServer  accepting socket (" + acceptExcp.GetType() +
                                            "). ->" +
                                            acceptExcp.Message);
                    }
                }

                Logger.Logger.Debug("RTSP server socket on " + m_localIPEndPoint + " listening halted.");
            }
            catch (Exception excp)
            {
                Logger.Logger.Error("Exception RTSPServer Listen. ->" + excp.Message);
            }
        }
Beispiel #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);
            }
        }
Beispiel #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);
            }
        }