/// <summary>
        /// Each client connection will be served by this thread.
        /// </summary>
        /// <param name="client"></param>
        private void ClientThread(object camobject)
        {
            ClientData clientdata = (ClientData)camobject;

            Socket socket = clientdata.client;

            string apAdress = socket.RemoteEndPoint.ToString();

            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + string.Format(".ClientThread.Connect({0})", apAdress), "WEB INFO");

            lock (_Clients)
                _Clients.Add(socket);

            try
            {
                if (callback != null)
                {
                    callback.OnClientConnect(clientdata.chanel, clientdata.stream);
                }

                using (MjpegWriter wr = new MjpegWriter(new NetworkStream(socket, true)))
                {
                    // Writes the response header to the client.
                    wr.WriteHeader();

                    // Streams the images from the source to the client.
                    foreach (var imgStream in Dvr.Streams(ImagesSource[socket]))
                    {
                        if (Interval > 0)
                        {
                            Thread.Sleep(Interval);
                        }

                        wr.Write(imgStream);
                    }
                }
            }
            catch (IOException e)
            {
                Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ClientThread.IOException(" + e.Message + ")", "WEB ERROR");
            }
            catch (Exception e)
            {
                Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ClientThread.Exception(" + e.Message + ")", "WEB ERROR");
            }
            finally
            {
                if (callback != null)
                {
                    callback.OnClientDisconnect(clientdata.chanel);
                }

                Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + string.Format(".ClientThread.Disconnect({0})", apAdress), "WEB INFO");

                socket.Close();

                lock (_Clients)
                    _Clients.Remove(socket);

                lock (ImagesSource)
                    ImagesSource.Remove(socket);
            }

            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ClientThread", "STOP THREAD");
        }
        /// <summary>
        /// This the main thread of the server that serves all the new
        /// connections from clients.
        /// </summary>
        /// <param name="state"></param>
        private void ServerThread(object state)
        {
            Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            Server.Bind(new IPEndPoint(IPAddress.Any, (int)state));
            Server.Listen(50);

            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + string.Format(".ServerThread({0})", state), "WEB INFO");

            foreach (Socket client in Server.IncommingConnectoins())
            {
                try
                {
                    byte[] bytes = new byte[1500];
                    client.Receive(bytes);
                    var    str  = Encoding.Default.GetString(bytes);
                    String path = GetLine(str, 1);
                    String host = GetLine(str, 2);

                    if (path.IndexOf("GET /favicon.ico", StringComparison.CurrentCultureIgnoreCase) == 0)
                    {
                        client.Close();
                    }
                    else if (path.IndexOf("GET /index.html", StringComparison.CurrentCultureIgnoreCase) == 0)
                    {
                        using (Stream stream = new NetworkStream(client, true))
                        {
                            string        adress = host.ToLower().Replace("host: ", "");
                            string        html   = @"<html><head></head><body>Life on http://" + adress + "/?chanel=X<br /> Shots on http://" + adress + "/?chanel_shot=X </body></html>";
                            StringBuilder sb     = new StringBuilder();
                            sb.AppendLine("HTTP/1.1 200 OK");
                            sb.AppendLine("content-type: text/html");
                            sb.AppendLine("connection: keep-alive");
                            sb.AppendLine("content-length: " + html.Length.ToString());
                            sb.AppendLine();
                            sb.AppendLine(html);

                            byte[] data_byte = Encoding.ASCII.GetBytes(sb.ToString());
                            stream.Write(data_byte, 0, data_byte.Length);
                        }

                        client.Close();
                    }
                    else if (path.IndexOf("GET /?chanel=", StringComparison.CurrentCultureIgnoreCase) == 0)
                    {
                        string chanel   = "0";
                        string streamid = "1";

                        string get = path.Split(new char[] { ' ' })[1];
                        get = get.Substring(2);
                        string[] paramArr = get.Split(new char[] { '&' });

                        foreach (string param in paramArr)
                        {
                            string[] paramsplit = param.Split(new char[] { '=' });
                            if (paramsplit[0] == "chanel")
                            {
                                chanel = paramsplit[1];
                            }
                            if (paramsplit[0] == "stream")
                            {
                                streamid = paramsplit[1];
                            }
                        }

                        //string param = "?chanel=";
                        //string chanel = path.Substring(path.IndexOf(param, StringComparison.CurrentCultureIgnoreCase) + param.Length, path.IndexOf(" ", path.IndexOf(param, StringComparison.CurrentCultureIgnoreCase)) - (path.IndexOf(param, StringComparison.CurrentCultureIgnoreCase) + param.Length));

                        lock (ImagesSource)
                            ImagesSource.Add(client, Dvr.Snapshots(chanel, imageData));
                        ClientData clientdata = new ClientData();
                        clientdata.client = client;
                        clientdata.chanel = Int32.Parse(chanel);
                        clientdata.stream = Int32.Parse(streamid);
                        ThreadPool.QueueUserWorkItem(new WaitCallback(ClientThread), clientdata);
                    }
                    else if (path.IndexOf("GET /?chanel_shot=", StringComparison.CurrentCultureIgnoreCase) == 0)
                    {
                        Stream stream     = new NetworkStream(client, true);
                        string chanel     = "0";
                        string streamid   = "0";
                        bool   chanelopen = false;
                        try
                        {
                            string get = path.Split(new char[] { ' ' })[1];
                            get = get.Substring(2);
                            string[] paramArr = get.Split(new char[] { '&' });

                            foreach (string param in paramArr)
                            {
                                string[] paramsplit = param.Split(new char[] { '=' });
                                if (paramsplit[0] == "chanel_shot")
                                {
                                    chanel = paramsplit[1];
                                }
                                if (paramsplit[0] == "stream")
                                {
                                    streamid = paramsplit[1];
                                }
                            }

                            if (callback != null)
                            {
                                callback.OnClientConnect(Int32.Parse(chanel), Int32.Parse(streamid));
                                chanelopen = true;
                            }
                            int counter = 0;
                            while (imageData.ContainsKey(chanel) != true && counter < 1000)
                            {
                                counter++;
                                Thread.Sleep(10);
                            }
                            if (counter == 1000)
                            {
                                client.Close();
                            }
                            else
                            {
                                Image        image = Image.FromStream(new MemoryStream(imageData[chanel]));
                                MemoryStream ms    = new MemoryStream();
                                image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

                                StringBuilder sb = new StringBuilder();
                                sb.AppendLine("HTTP/1.1 200 OK");
                                sb.AppendLine("Connection: keep-alive");
                                sb.AppendLine("Content-Type: image/jpeg");
                                sb.AppendLine("Content-Length: " + ms.Length.ToString());
                                sb.AppendLine();
                                byte[] data_byte = Encoding.ASCII.GetBytes(sb.ToString());

                                stream.Write(data_byte, 0, data_byte.Length);
                                ms.WriteTo(stream);

                                stream.Flush();
                            }
                            if (callback != null && chanelopen)
                            {
                                callback.OnClientDisconnect(Int32.Parse(chanel));
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ServerThread.Exception(" + e.Message + ")", "WEB ERROR");
                        }
                        finally
                        {
                            Thread.Sleep(100);
                            client.Close();
                        }
                    }
                    else
                    {
                        using (Stream stream = new NetworkStream(client, true))
                        {
                            StringBuilder sb = new StringBuilder();
                            sb.AppendLine("HTTP/1.1 301 Moved Permanently");
                            sb.AppendLine("Location: /index.html");
                            sb.AppendLine();

                            byte[] data_byte = Encoding.ASCII.GetBytes(sb.ToString());
                            stream.Write(data_byte, 0, data_byte.Length);
                        }

                        client.Close();
                    }
                }
                catch (SocketException e)
                {
                    Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ServerThread.SocketException(" + e.Message + ")", "WEB ERROR");
                    Debug.WriteLine(e.ToString());
                }
                catch (Exception e)
                {
                    Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ServerThread.Exception(" + e.Message + ")", "WEB ERROR");
                    Debug.WriteLine(e.ToString());
                }
            }

            Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss - ") + TAG + ".ServerThread", "STOP THREAD");

            Stop();
        }