套接字无法正常工作,因为它应该有帮助

本文关键字:因为 有帮助 工作 常工作 套接字 | 更新日期: 2023-09-27 17:48:54

我制作了一个基于客户端和服务器套接字的GUI应用程序,其中捕获屏幕并通过套接字将其传输到所需的Listner,但是我得到了一个黑色的放置图像接收器端或客户端图像在服务器上,但无法在我的客户端应用程序中显示它只是显示黑色图片?

代码为 : 服务器

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");
      }

    }
}

套接字无法正常工作,因为它应该有帮助

这是一个相当完整(尽管快速且肮脏)的解决方案:

服务器:

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"和单个图片框:"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);
        }
    }
}

仅仅因为您通过一次调用发送图像 Send(...) ,不太可能(除非图像很小,如果是屏幕截图,则可能不是)通过对客户端Receive(...)的一次调用来完全接收它。

您将需要反复调用Receive(...),建立接收到的图像缓冲区,直到Receive(...)返回 0,表示套接字已关闭。然后,您应该拥有完整的图像以供显示。

不确定您的实际问题是什么,但我注意到byteArrayToImage()中存在一个潜在的错误; 您必须在图像的生命周期内保持流打开状态(是的,它不是最常用的.NET API方法! http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx

我使用了 tcp 客户端和 listner 方法,它工作正常,但在接收器端有一个 prob,它只显示图像的 1/4 并抛出异常 未建立连接.. 现在什么是 prb

公共分部类 表格 1 : 表格 { 私有静态位图bmp截图; 布尔开始 = 假; 私有静态图形 gfx截图;

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

就像@Iridium提到的,你需要循环 Read()-ing,直到没有收到更多的数据。

另外,请查看MemoryStream以替换所有数组元素洗牌。一个简单的Array.CopyTo已经是复制字节数组代码的巨大改进。