@Meezmo
Python, C# programmer

Как сделать трансляцию экрана через сокеты в C#?

Написал простенькую программу для управления компьютером через сокеты (TCP). Среди её функций есть трансляция экрана. Сервер делает скриншот и отправляет этот байтовый массив клиенту, который его получает и выводит на экран. Проблема в том, что каждый раз когда сервер отправляет изображение, клиент его получает и соединение сразу разрывается, и сразу создаётся ещё раз. Можно ли как то сделать так, чтобы клиент непрерывно получал скриншоты не разрывая соединения?
Вот кусок кода из сервера:
private void SendScreenshot()
        {
            Socket listener = new(IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(sendScreenshotEndPoint);
            listener.Listen(10);
            while (true) // безконечный цикл прослушивания
            {
                Socket handler = listener.Accept();
                Console.WriteLine("Connected");
                try
                {
                    byte[] buffer = Screenshot.MakeScreenshot();
                    handler.Send(buffer, buffer.Length, SocketFlags.None);
                }
                catch (SocketException)
                {
                    handler.Shutdown(SocketShutdown.Both);
                    Console.WriteLine("Connection aborted");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"ERROR: {e}");
                    byte[] msg = Encoding.UTF8.GetBytes("ERROR");
                    handler.Send(msg);
                }
                handler.Close();
            }
        }

И клиента:
public void StreamScreen()
        {
            streamScreen = true;
            while (streamScreen)
            {
                try
                {
                    using Stream stream = new MemoryStream(socketRequests.GetScreenshotRequest());
                    BitmapImage image = new();
                    stream.Position = 0;
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = stream;
                    image.EndInit();
                    image.Freeze();
                    Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate
                    {
                        ScreenshotImage.Source = image;
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Fatal error", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.Yes);
                }
            }
        }

// функция получения скриншота
public byte[] GetScreenshotRequest()
        {
            Socket socketSender = socketInfo.AutoSocket;
            socketSender.Connect(socketInfo.GetScreenshotEndpoint);
            byte[] bytes = ReceiveAll(socketSender);
            return bytes;
        }

public static byte[] ReceiveAll(Socket SocketSender)
        {
            List<byte> buffer = new();
            while (true) // бредовый бесконечный цикл, но пока что пускай будет
            {
                byte[] currByte = new byte[1];
                int byteCounter = SocketSender.Receive(currByte, currByte.Length, SocketFlags.None);
                if (byteCounter == 0)
                {
                    return buffer.ToArray();
                }
                else
                {
                    buffer.Add(currByte[0]);
                }
            }
        }


P.S. Наверное много говнокода есть, да и с сокетами первый раз работаю, делал программу чисто ради интереса.
  • Вопрос задан
  • 503 просмотра
Решения вопроса 1
@rPman
ты хандлер сокета клиента закрыл сразу после отправки
убери handler.Close();

upd. еще подумай, что будет если к твоему сервису подключится второй клиент, т.е. listener.accept должен создавать новый хандлер который как то нужно обрабатывать либо вообще выноси из цикла accept (второй сделай вложенный) и пока клиент хандлер не закроет, тупо шли в него картинки.

Еще момент, ты должен как то сообщить клиенту, сколько данных будешь передавать, например сначала шлешь размер буфера с изображением, а затем сам буфер. Само собой клиент точно так же должен это ожидать
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Вот. Не благодари

private void SendScreenshot(Socker handler) {
 ....
}

и handler не закрывай.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы