/// <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(); }