ScreenExtenderServer.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using ScreenExtender.Resources;
  2. using System.IO;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. namespace ScreenExtender
  9. {
  10. internal class ScreenExtenderServer
  11. {
  12. private readonly ScreenExtenderMainForm _mainForm;
  13. private Socket _server;
  14. private bool _isRunning;
  15. public ScreenExtenderServer(ScreenExtenderMainForm mainForm)
  16. {
  17. _mainForm = mainForm;
  18. }
  19. public void Start(IPAddress listen, int port)
  20. {
  21. _server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  22. _server.Bind(new IPEndPoint(listen, port));
  23. _server.Listen(1);
  24. _isRunning = true;
  25. Task.Factory.StartNew(ServerProc);
  26. }
  27. public void Stop()
  28. {
  29. _isRunning = false;
  30. _server?.Close();
  31. _server?.Dispose();
  32. }
  33. private void ServerProc()
  34. {
  35. while (_isRunning)
  36. {
  37. var client = _server.Accept();
  38. Task.Factory.StartNew(() => RequestProc(client));
  39. }
  40. }
  41. private void RequestProc(Socket client)
  42. {
  43. string req = "";
  44. {
  45. var buf = new byte[4096];
  46. var len = client.Receive(buf, 0, buf.Length, SocketFlags.None);
  47. //detect request
  48. var text = Encoding.ASCII.GetString(buf, 0, len);
  49. var lines = text.Split('\r', '\n');
  50. if (lines.Length > 0 && lines[0].StartsWith("GET"))
  51. {
  52. var parts = lines[0].Split(new[] { ' ' }, 3);
  53. if (parts.Length > 1) req = parts[1];
  54. }
  55. }
  56. var stream = new NetworkStream(client, true);
  57. if (req == "")
  58. {
  59. var ns = new NetworkStream(client);
  60. var w = new BinaryWriter(ns);
  61. while (_isRunning)
  62. {
  63. Thread.Sleep(100);
  64. var rBuf = _mainForm.FrameBytes;
  65. if (rBuf == null) continue;
  66. try
  67. {
  68. w.Write(rBuf.Length);
  69. w.Write(rBuf);
  70. }
  71. catch (IOException)
  72. {
  73. break;
  74. }
  75. }
  76. client.Close();
  77. }
  78. var path = req.Split('?')[0];
  79. switch (path)
  80. {
  81. case "/":
  82. {
  83. var rBuf = ResourceFetcher.IndexPage;
  84. var writer = new BinaryWriter(stream);
  85. writer.Write(Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\n"));
  86. writer.Write(Encoding.ASCII.GetBytes("Content-Type: text/html\r\n"));
  87. writer.Write(Encoding.ASCII.GetBytes("Content-Length: " + rBuf.Length + "\r\n"));
  88. writer.Write(Encoding.ASCII.GetBytes("\r\n"));
  89. writer.Write(rBuf);
  90. writer.Close();
  91. client.Close();
  92. }
  93. break;
  94. case "/mjpeg":
  95. {
  96. var writer = new BinaryWriter(stream);
  97. writer.Write(Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\n"));
  98. writer.Write(Encoding.ASCII.GetBytes("Content-Type: multipart/x-mixed-replace; boundary=frame\r\n"));
  99. while (_isRunning)
  100. {
  101. var rBuf = _mainForm.FrameBytes;
  102. if (rBuf == null)
  103. {
  104. Thread.Sleep(100);
  105. continue;
  106. }
  107. writer.Write(Encoding.ASCII.GetBytes("\r\n"));
  108. writer.Write(Encoding.ASCII.GetBytes("--frame\r\n"));
  109. writer.Write(Encoding.ASCII.GetBytes("Content-Type: image/png\r\n"));
  110. writer.Write(Encoding.ASCII.GetBytes("Content-Length: " + rBuf.Length + "\r\n"));
  111. writer.Write(Encoding.ASCII.GetBytes("\r\n"));
  112. writer.Write(rBuf);
  113. }
  114. client.Shutdown(SocketShutdown.Both);
  115. client.Close();
  116. client.Dispose();
  117. }
  118. break;
  119. case "/frame": //Single Picture Download,close
  120. {
  121. byte[] rBuf;
  122. do
  123. {
  124. rBuf = _mainForm.FrameBytes;
  125. if (rBuf != null) break;
  126. Thread.Sleep(100);
  127. } while (true);
  128. var writer = new BinaryWriter(stream);
  129. writer.Write(Encoding.ASCII.GetBytes("HTTP/1.1 200 OK\r\n"));
  130. writer.Write(Encoding.ASCII.GetBytes("Content-Type: image/png\r\n"));
  131. writer.Write(Encoding.ASCII.GetBytes("Content-Length: " + rBuf.Length + "\r\n"));
  132. writer.Write(Encoding.ASCII.GetBytes("\r\n"));
  133. writer.Write(rBuf);
  134. writer.Close();
  135. client.Close();
  136. }
  137. break;
  138. default:
  139. client.Close();
  140. break;
  141. }
  142. }
  143. }
  144. }