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

时间:2011-04-03 04:55:48

标签: c# sockets

我做了一个基于客户端和服务器套接字的gui应用程序,其中屏幕被捕获,并通过套接字它被转移到所需的列表,但我得到一个黑色输出图像接收器端或客户端图像在服务器但不能显示它在我的客户端应用程序中只显示黑色图片?

代码为:server

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 个答案:

答案 0 :(得分:1)

这是一个相当完整(虽然快速和肮脏)的解决方案:

服务器:

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

仅仅因为您通过一次调用Send(...)发送图像,它是非常不可能的(除非图像很小,如果它是截图,它可能不是),它将被完全接收在客户端单次调用Receive(...)

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

答案 3 :(得分:0)

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

公共部分类Form1:表单     {         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();
        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();
    }

    }

答案 4 :(得分:0)

与提到的@Iridium一样,你需要循环Read() - 直到不再收到数据。

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