Arslan Pervaiz
Arslan Pervaiz

Reputation: 3

Sending and receiving an image over sockets with C# | Screen Sharing Using C#

I am trying to set up two programs in C#. Basically, a simple server side set up where I want the client to listen for an image from the Server. Then, upon receiving the image, will display it in a PictureBox.

**I keep running into the following error:

A first chance exception of type 'System.ArgumentException' occurred in System.Drawing.dll or Parameter is not Valid**

SERVER SIDE

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ServerComputer
{
    public partial class mainForm : Form
    {
        public mainForm()
        {
            InitializeComponent();
        }
        Socket sendsocket;
        private void goLive_Click(object sender, EventArgs e)
        {
            try
            {
                sendsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //The instantiation of socket, IP for 192.168.1.106, 10001 for Port
                IPEndPoint ipendpiont = new IPEndPoint(IPAddress.Parse(ipAddress.Text.Trim()), 10001);
                sendsocket.Connect(ipendpiont);
                //Establishment of end point
                Thread th = new Thread(new ThreadStart(threadimage));
                th.IsBackground = true;
                th.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            this.Hide();    //Hidden form
        }
        private Bitmap GetScreen()
        {
            Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics g = Graphics.FromImage(bitmap);
            g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
            return bitmap;
        }
        private void threadimage()
        {
            try
            {
                while (true)
                {
                    MemoryStream ms = new MemoryStream();
                    GetScreen().Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);   //Here I use the BMP format
                    byte[] b = ms.ToArray();
                    sendsocket.Send(b);
                    Thread.Sleep(67);     //I'm here to set to send a second
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                return;
            }
        }
    }
}

CLIENT SIDE

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ClientComputer
{
    public partial class mainForm : Form
    {
        public mainForm()
        {
            InitializeComponent();
        }
        Socket hostSocket;
        Thread thread;
        string localIP = string.Empty;
        string computrHostName = string.Empty;
        private void mainForm_Load(object sender, EventArgs e)
        {
            computrHostName = Dns.GetHostName();
            IPHostEntry hostname = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in hostname.AddressList)
            {
                if (ip.AddressFamily.ToString() == "InterNetwork")
                {
                    localIP = ip.ToString();
                }
            }
        }
        private void liveScreen_Click(object sender, EventArgs e)
        {
            Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse(localIP), 10001);
            //Connection node
            receiveSocket.Bind(hostIpEndPoint);
            receiveSocket.Listen(10);
            MessageBox.Show("start");
            hostSocket = receiveSocket.Accept();
            thread = new Thread(trreadimage);
            thread.Start();
            thread.IsBackground = true;
        }
        private void trreadimage()
        {
            int dataSize, i = 0;
            try
            {
                while (true)
                {
                    i++;
                    byte[] b = new byte[1024 * 1024 * 20];  //Picture of great
                    dataSize = hostSocket.Receive(b,0,b.Length,SocketFlags.None);
                    MemoryStream ms = new MemoryStream(b,0,dataSize,true);
                    //bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    Image img = Image.FromStream(ms);
                    img.Save("Image"+i+".Jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    videoBox.Image = img;
                    Console.WriteLine("Image Size: " + dataSize);
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                thread.Abort();
            }
        }
    }
}

Upvotes: 0

Views: 2873

Answers (3)

Mohamed Mohamedein
Mohamed Mohamedein

Reputation: 69

MemoryStream ms = new MemoryStream(b);
Image img = Image.FromStream(ms);
img.Save(imageName, System.Drawing.Imaging.ImageFormat.Jpeg);
videoBox.Image = img;

The error may due to corrupted or incomplete bmp image received in the MemoryStream it worked fine for me after increasing the socket send/receive buffers values so adjust the sender "Socket.SendBufferSize" and the receiver "Socket.ReceiveBufferSize" to large values for example SendBufferSize = 1024 * 1024 * 20 this will help sending the entire image at once. or another solution is to check whether the received data size (b.length) is the same as the sent image data size, before the code line of forming the received image stream

Upvotes: 0

Yury Schkatula
Yury Schkatula

Reputation: 5369

I can't stop repeating: never ever send raw data to a socket and expect to receive them the same way on another end. Use a protocol instead, to describe your network activity. In simplest case, send DWORD first that designated total length of your image. Same time, it's worth to reuse existing protocols like HTTP or what can fit your needs.

Why to bother? Well, if your "network" is just a piece of wire with two jacks on ends that placed directly into network cards of your PCs, that maybe happen to work OK (and still no 100% warranty). In real case, your "network connection" is a pack of inter-connections between routers, firewalls, switches and all that sort of hidden machinery in-between. They can (and will!) re-shape your stream the way they find useful for them. So, on the other end, how can your counterparty understand: is there everything received? how many packets to expect? etc. etc. etc.

So, sending some business data directly to socket is the same efficient as yelling to the window if you plan to say something to your friend living nearby. And, usually we use a phone with that kind of communication protocol "hey, Peter?.. yes, it's me.. listen, take care about your car as hail shower is coming... Bye!". See the difference?

Upvotes: 1

Sohail Ahmad
Sohail Ahmad

Reputation: 86

Following code is working now, and I have few suggestions,

Try Async methods/events to receive and send data through socket instead of using loop or recursive methods.

Server Code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ServerComputer
{
    publicpartialclassmainForm : Form
    {
        public mainForm()
        {
            InitializeComponent();
        }
        Socket sendsocket;
        privatevoid goLive_Click(object sender, EventArgs e)
        {
            try
            {
                sendsocket = newSocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //The instantiation of socket, IP for 192.168.1.106, 10001 for PortIPEndPoint ipendpiont = newIPEndPoint(IPAddress.Parse(ipAddress.Text.Trim()), 10001);
                sendsocket.Connect(ipendpiont);
                //Establishment of end pointThread th = newThread(newThreadStart(threadimage));
                th.IsBackground = true;
                th.Start();
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
                return;
            }
            this.Hide();    //Hidden form
        }
        privateBitmap GetScreen()
        {
            Bitmap bitmap = newBitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Graphics g = Graphics.FromImage(bitmap);
            g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
            return bitmap;
        }
        privatevoid threadimage()
        {
            try
            {
                MemoryStream ms = newMemoryStream();
                GetScreen().Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);   //Here I use the BMP formatbyte[] b = ms.ToArray();

                sendsocket.Send(b);
                ms.Close();


            }
            catch (Exception ee)
            {
                // MessageBox.Show(ee.Message);//return;
            }

            Thread.Sleep(1000);
            threadimage();
        }
    }
}

Clint Code.

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

namespace ClientComputer
{
    public partial class mainForm : Form
    {
        public mainForm()
        {
            InitializeComponent();
        }
        Socket hostSocket;
        Thread thread;
        string localIP = string.Empty;
        string computrHostName = string.Empty;
        private void mainForm_Load(object sender, EventArgs e)
        {
            computrHostName = Dns.GetHostName();
            IPHostEntry hostname = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in hostname.AddressList)
            {
                if (ip.AddressFamily.ToString() == "InterNetwork")
                {
                    localIP = ip.ToString();
                }
            }
            this.Text = this.Text + " | " + localIP;

        }
        private void liveScreen_Click(object sender, EventArgs e)
        {
            connectSocket();
        }

        private void connectSocket()
        {
            Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse(localIP), 10001);
            //Connection node
            receiveSocket.Bind(hostIpEndPoint);
            receiveSocket.Listen(10);
            MessageBox.Show("start");
            hostSocket = receiveSocket.Accept();
            thread = new Thread(new ThreadStart(trreadimage));

            thread.IsBackground = true;
            thread.Start();
        }
        private void trreadimage()
        {
            int dataSize;
            string imageName = "Image-" + System.DateTime.Now.Ticks + ".JPG";
            try
            {

                dataSize = 0;
                byte[] b = new byte[1024 * 10000];  //Picture of great
                dataSize = hostSocket.Receive(b);
                if (dataSize > 0)
                {
                    MemoryStream ms = new MemoryStream(b);
                    Image img = Image.FromStream(ms);
                    img.Save(imageName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    videoBox.Image = img;
                    ms.Close();
                }

            }
            catch (Exception ee)
            {
                //MessageBox.Show(ee.Message);
                //thread.Abort();
            }
            System.Threading.Thread.Sleep(1500);
            trreadimage();
        }
    }
}

Upvotes: 0

Related Questions