Разъем не работает, как это должно помочь! - PullRequest
1 голос
/ 03 апреля 2011

Я сделал приложение на основе сокета клиента и сервера, в котором снимок экрана и через сокет он передается нужному списку, но я получаю затемненное изображение получателя или клиента, изображение находится на сервере, но не может показать это в моем клиентском приложении это просто показать черную картинку?

код как: сервер

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Net.Sockets;
using System.IO;
using System.Net;

namespace LanMonitoring
{
    public partial class Form1 : Form
    {
      private static Bitmap bmpScreenshot;
      bool start = false;
      private static Graphics gfxScreenshot;

      public Form1()
      {
        InitializeComponent();
        button2.Enabled = false;
      }

      private void button1_Click(object sender, EventArgs e)
      {           
        button1.Enabled = false;
        button2.Enabled = true;
        start = true;

        fillpic();
      }
      public void fillpic()
      {
        bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
        gfxScreenshot = Graphics.FromImage(bmpScreenshot);
        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
        pictureBox1.Image = bmpScreenshot;
        sendbmp(bmpScreenshot);
      }


      private void button2_Click(object sender, EventArgs e)
      {

        button1.Enabled = true;
        button2.Enabled = false;
        start = false;
      }
      public void sendbmp(Bitmap bmp)
      {
        Socket mm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(textBox1.Text), 5002);
        try
        {
          mm.Connect(remoteEP);
        }
        catch (Exception)
        {
          sendbmp(bmpScreenshot);
        }
        Image temp = bmp;
        byte[] buf = imageToByteArray(temp);
        mm.Send(buf);
        mm.Close();
     }
      public byte[] imageToByteArray(System.Drawing.Image imageIn)
      {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
        return ms.ToArray();
      }


      public Image byteArrayToImage(byte[] byteArrayIn)
      {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms);
        return returnImage;
      }

    }
}

клиент как:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Net;
namespace LanReciver
{
    public partial class Client : Form
    {

      byte[] buf = new byte[5000];
      public Client()
      {
        InitializeComponent();

      }

      private void button1_Click(object sender, EventArgs e)
      {
        backgroundWorker1.RunWorkerAsync();
      }
      public void call()
      {
        Socket mm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        mm.Bind(new IPEndPoint(0, 5002));
        mm.Listen(100);
        Socket acc = mm.Accept();
        buf = new byte[acc.SendBufferSize];
        int byteread = acc.Receive(buf);
        byte[] rev = new byte[byteread];
        for (int i = 0; i < byteread; i++)
        {
          rev[i] = buf[i];
        }
        byteArrayToImage(rev);
        mm.Close();
        acc.Close();
        call();
      }

      public Image byteArrayToImage(byte[] byteArrayIn)
      {
        MemoryStream ms = new MemoryStream(byteArrayIn);
        Image returnImage = Image.FromStream(ms);
        return returnImage;
      }

      private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
      {
        call();
      }

      private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
        MessageBox.Show("Recieved");
      }


    }
}

Ответы [ 5 ]

1 голос
/ 07 апреля 2011

Вот довольно полное (хотя и быстрое и грязное) решение:

Сервер:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;

namespace ImageServer
{
    static class Program
    {
        static void Main()
        {
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Bind(new IPEndPoint(IPAddress.Any, 23456));
                socket.Listen(100);
                while (true)
                {
                    using (var client = socket.Accept())
                    {
                        var bounds = Screen.PrimaryScreen.Bounds;
                        var bitmap = new Bitmap(bounds.Width, bounds.Height);
                        try
                        {
                            while (true)
                            {
                                using (var graphics = Graphics.FromImage(bitmap))
                                {
                                    graphics.CopyFromScreen(bounds.X, 0, bounds.Y, 0, bounds.Size);
                                }
                                byte[] imageData;
                                using (var stream = new MemoryStream())
                                {
                                    bitmap.Save(stream, ImageFormat.Png);
                                    imageData = stream.ToArray();
                                }
                                var lengthData = BitConverter.GetBytes(imageData.Length);
                                if (client.Send(lengthData) < lengthData.Length) break;
                                if (client.Send(imageData) < imageData.Length) break;
                                Thread.Sleep(1000);
                            }
                        }
                        catch
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
}

Клиент (форма с одной кнопкой: «button1» и одним pictureBox: «pictureBox1»):

using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;

namespace ImageClient
{
    public partial class Form1 : Form
    {
        private Bitmap _buffer;

        public Form1()
        {
            InitializeComponent();
        }

        private void Button1Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            ThreadPool.QueueUserWorkItem(GetSnapshots);
        }

        private void GetSnapshots(object state)
        {
            using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
            {
                socket.Connect(new IPEndPoint(IPAddress.Loopback, 23456));
                while (true)
                {
                    var lengthData = new byte[4];
                    var lengthBytesRead = 0;
                    while (lengthBytesRead < lengthData.Length)
                    {
                        var read = socket.Receive(lengthData, lengthBytesRead, lengthData.Length - lengthBytesRead, SocketFlags.None);
                        if (read == 0) return;
                        lengthBytesRead += read;
                    }
                    var length = BitConverter.ToInt32(lengthData, 0);
                    var imageData = new byte[length];
                    var imageBytesRead = 0;
                    while (imageBytesRead < imageData.Length)
                    {
                        var read = socket.Receive(imageData, imageBytesRead, imageData.Length - imageBytesRead, SocketFlags.None);
                        if (read == 0) return;
                        imageBytesRead += read;
                    }
                    using (var stream = new MemoryStream(imageData))
                    {
                        var bitmap = new Bitmap(stream);
                        Invoke(new ImageCompleteDelegate(ImageComplete), new object[] { bitmap });
                    }
                }
            }
        }

        private delegate void ImageCompleteDelegate(Bitmap bitmap);
        private void ImageComplete(Bitmap bitmap)
        {
            if (_buffer != null)
            {
                _buffer.Dispose();
            }
            _buffer = new Bitmap(bitmap);
            pictureBox1.Size = _buffer.Size;
            pictureBox1.Invalidate();
        }

        private void PictureBox1Paint(object sender, PaintEventArgs e)
        {
            if (_buffer == null) return;
            e.Graphics.DrawImage(_buffer, 0, 0);
        }
    }
}
0 голосов
/ 04 апреля 2011

Как упомянуто @Iridium, вам нужно зацикливать Read () - до тех пор, пока не будет получено больше данных.

Также, пожалуйста посмотрите на MemoryStream, чтобы заменить все перемешивание элемента массива.Простой Array.CopyTo уже был бы огромным недостатком кода, который вы должны скопировать байтовые массивы

0 голосов
/ 03 апреля 2011

Только из-за того, что вы отправляете изображение с одним вызовом на Send(...), очень маловероятно (если изображение не маленькое, а если это снимок экрана, вероятно, это не так), что оно будет получено полностью с одним позвоните на номер Receive(...) на стороне клиента.

Вам нужно будет повторно вызывать Receive(...), создавая буфер полученного изображения, пока Receive(...) не вернет 0, указывая, что сокет был закрыт. После этого у вас должно быть полное изображение для отображения.

0 голосов
/ 04 апреля 2011

Я использовал метод tcp client и listner, и он работал нормально, но с одним пробником на стороне получателя он показывает только 1/4 изображения и выбрасывает исключение, соединение не было установлено.

открытый частичный класс Form1: Form {частный статический битмап bmpScreenshot;bool start = false;приватная статическая графика gfxScreenshot;

    public Form1()
    {
        InitializeComponent();
        button2.Enabled = false;
    }

    private void button1_Click(object sender, EventArgs e)
    {                   
        button1.Enabled = false;
        button2.Enabled = true;
        start = true;
        fillpic();
        backgroundWorker1.RunWorkerAsync();
    }
    public void fillpic()
    {
        bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
        gfxScreenshot = Graphics.FromImage(bmpScreenshot);
        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
        pictureBox1.Image = bmpScreenshot;
     }


    private void button2_Click(object sender, EventArgs e)
    {

        button1.Enabled = true;
        button2.Enabled = false;
        start = false;
    }

    public byte[] imageToByteArray(System.Drawing.Image imageIn)
    {
        MemoryStream ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        return ms.ToArray();
    }



    public void caal()
    {
        TcpClient TCPC = new TcpClient();
        TCPC.Connect("127.0.0.1", 5002);
        if (TCPC.Connected)
        {
            NetworkStream ns = TCPC.GetStream();
            while (ns.CanWrite)
            {
                fillpic();
                byte[] data = imageToByteArray(bmpScreenshot);
                ns.Write(data, 0, data.Length);
            }
        }   
    }


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        caal();
    }

    }
0 голосов
/ 03 апреля 2011

Не уверен, в чем ваша проблема, но я заметил, что в byteArrayToImage() есть потенциальная ошибка;Вы должны держать поток открытым в течение всего времени жизни изображения (да, это не самый удобный метод .NET API!): http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...