Отправка данных через сокеты - C#
Формулировка задачи:
Здравствуйте. Я сделал программу (Точнее 2 : сервер и клиент). Суть клиента - отправить скриншот экрана, сервера - принять и сохранить скриншот. С этой задачей программа справляется, но есть несколько нюансов :
1. Чем больше буффер приема данных, тем больше шанс того, что картинка будет частично (А бывает и полностью) черной.
2. Программа оочень медленная. При значении буффера 1 (Когда скриншоты не искажаются) для 1 скриншота тратится 5 секунд. А ведь если использовать 4к разрешение, то там и все 20-30 секунд уйдут.
Вот код :
Сервер
Клиент
Очень сильно нагружает сервер то, что скриншот отправляется кусочками, эти кусочки собираются в массиве типа List, а потом, когда все кусочки собраны, все данные из List переписываются в массив, а массив обрабатывается и становится картинкой.
Клиент же преобразует скриншот в массив байтов и отправляет.
Чем вызвана первая проблема? Как ее исправить?
Как можно более рациональным способ решить проблему 2?
Буду преблагодарен всем тем, кто помог решить проблемы.
Socket _ClientS = _ServerS.Accept();
Console.WriteLine("Соединение установлено");
List<byte> _Data = new List<byte>();
int _Bytes = 0;
byte[] _Buffer = new byte[64];
do
{
_Bytes = _ClientS.Receive(_Buffer);
for (int i = 0; i < _Buffer.Length; i++)
{
_Data.Add(_Buffer[i]);
}
}
while (_ClientS.Available > 0);
byte[] _BData = new byte[_Data.Count];
for (int i = 0; i < _Data.Count; i++)
{
_BData[i] = _Data[i];
}Socket _ClientS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Thread.Sleep(100);
_ClientS.Connect(_IpEndP);
//Console.WriteLine("Нажмите на любую кнопку для создания скриншота...");
//Console.ReadKey();
Bitmap _BitMap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppRgb);
using (Graphics _Gr = Graphics.FromImage(_BitMap))
{
_Gr.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
}
byte[] _Data = null;
BitmapData _BData = _BitMap.LockBits(new Rectangle(new Point(), _BitMap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
int _ByteCount = _BData.Stride * _BitMap.Height;
_Data = new Byte[_ByteCount];
Marshal.Copy(_BData.Scan0, _Data, 0, _ByteCount);
_BitMap.UnlockBits(_BData);
_ClientS.Send(_Data);
_ClientS.Shutdown(SocketShutdown.Both);
_ClientS.Close();Решение задачи: «Отправка данных через сокеты»
textual
Листинг программы
Socket _ClientS = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Thread.Sleep(100);
_ClientS.Connect(_IpEndP);
//Console.WriteLine("Нажмите на любую кнопку для создания скриншота...");
//Console.ReadKey();
using(Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppRgb))
using(Graphics g = Graphics.FromImage(bitmap))
using(MemoryStream ms = new MemoryStream())
{
g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
bitmap.Save(ms, ImageFormat.Png);
_ClientS.Send(ms.ToArray());
_ClientS.Shutdown(SocketShutdown.Both);
_ClientS.Close();
}