Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to send the pictures from my desktop which I get them by a timer. the client version receives the first picture and doesn't get another picture from timer of server version.
this is the server version code:


C#
using System.Net;
using System.IO;
using System.Net.Sockets;
Graphics g;
byte[] msg = new byte[1024];
int msglen;
byte[] sendmsg = new byte[1024];
Socket sktlis;
byte[] ib = new byte[20000];

private void btnConnect_Click(object sender, EventArgs e)
    {
        sktlis = new Socket(AddressFamily.InterNetwork, SocketType.Stream,        ProtocolType.Tcp);
        IPEndPoint iplocal = new IPEndPoint(IPAddress.Any, Convert.ToInt32(txtPort.Text));
        sktlis.Bind(iplocal);
        sktlis.Listen(1);
        lblStatus.Text = "connected";
        sktlis = sktlis.Accept();
        tt = true;
        timer2.Enabled = true;
    }

   private void timer2_Tick(object sender, EventArgs e)
    {

        Bitmap bmpScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        g = Graphics.FromImage(bmpScreenCapture);
        g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                     Screen.PrimaryScreen.Bounds.Y,
                     0, 0,
                     bmpScreenCapture.Size,
                     CopyPixelOperation.SourceCopy);
        MemoryStream ms = new MemoryStream();

        bmpScreenCapture.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
        ib = ms.ToArray();
        Image aa = Image.FromStream(ms);
        Bitmap objBitmap = new Bitmap(aa, new Size(500, 200));
        picR.Image = objBitmap;
        sktlis.Send(ib);


    }


and this is the client version:

C#
 byte[] msg = new byte[20000];
    byte[] msgtest = new byte[20000];
    int  msglen;
    MemoryStream msc = new MemoryStream();
    Image aa;
    Boolean tt = false;
    static Socket sktlisc;
    byte[] answer = new byte[1024];

private void btnConnect_Click(object sender, EventArgs e)
{
    sktlisc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPHostEntry iphe = Dns.Resolve(txtIc.Text);
    IPAddress ipa = iphe.AddressList[0];
    IPEndPoint iplocal = new IPEndPoint(ipa,Convert.ToInt32(txtPort.Text));
    sktlisc.Connect(iplocal);
    lblStatus.Text = "Connected";
    tt = true;
    timer1.Enabled = true;
}

private void timer1_Tick(object sender, EventArgs e)
{

    if (tt)
    {
        if (sktlisc.Available != 0)
        {
            msglen = sktlisc.Receive(msg);

            msc.Write(msg, 0, msglen);
            aa = Image.FromStream(msc);

            Bitmap objBitmap = new Bitmap(aa, new Size(500, 200));

            picR.Image = objBitmap;

        }
    }
}
Posted
Comments
gggustafson 19-May-14 11:54am    
A couple of questions:

1. How do you know that your client isn't receiving the picture. From what I see, once you click on the server's connect button, the server keeps sending the picture. If the screen doesn't change, you will not see a change on the client.

2. Why are you using a connect button on both the server and the client. All the connect button on the server does is set up the timer. But it takes another connect button click on the client

Suggestion: use a traditional client/server mechanism. Google "C# client server" to get a large number of useful links.
A wo 19-May-14 16:24pm    
in the server version all picture change in time but in the client version just show first picture and i don't know that if server version don't keep sending or client version don't receiving picture<br>
i am wating for your help<br>
tnks
gggustafson 22-May-14 14:19pm    
Are you going to rate my solution>

1 solution


Sorry for the delay. Some thoughts on client/servers.



The client always controls the interaction. This means that the server is silent until contacted by the client (the server is actually in some form of listening state). This means that your use of a push is wrong. There should be no timer on the server side. Only when the client connects to the server should the server prepare and send the data.



On the client side, I'd suggest that you initially not use a timer. It just confuses the debugging process. Rather each time that a "connect" button is clicked, the client connects to the server and awaits the server's response.



This is the classic client/server paradigm.



You are collecting an enormous amount of data. My monitor screen resolution is 1920x1080. That's 8294400 bytes that need to be transmitted. Since you have chosen TCP (rather than UDP), the image requires about 5525 packets to cross from the server to the client (assuming an MTU of 1400 bytes, a nominal value). At a bandwidth of 16mbit/sec, that amount of data will take (optimally) more than four seconds. So your timer must be set to greater than that value. If you follow my recommendation that server only responds when contacted, then the client can adjust its connect timing to account for the transit time. See maximum packet size for a TCP connection[^] for a discussion of MTU.



If you can concentrate on only one window on the desktop, there are ways in which an image of that window can be captured. That will significantly reduce that amount of data you must transmit. The following code performs the window to image capture.


C#
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

// **************************************** class CaptureDesktopWindow

public class CaptureDesktopWindow
    {

    const int SRCCOPY = 0x00CC0020;     // BitBlt dwRop

    [ StructLayout ( LayoutKind.Sequential ) ]
    struct RECT
        {
        public int left;
        public int top;
        public int right;
        public int bottom;
        }

    [ DllImport ( "gdi32.dll" ) ]
    static extern bool BitBlt ( IntPtr   hObject, 
                                int      nXDest, 
                                int      nYDest,
                                int      nWidth, 
                                int      nHeight, 
                                IntPtr   hObjectSource,
                                int      nXSrc, 
                                int      nYSrc, 
                                int      dwRop );

    [ DllImport ( "gdi32.dll" ) ]
    static extern IntPtr CreateCompatibleBitmap ( IntPtr hDC, 
                                                  int nWidth,
                                                  int nHeight );

    [ DllImport ( "gdi32.dll" ) ]
    static extern IntPtr CreateCompatibleDC ( IntPtr hDC );

    [ DllImport ( "gdi32.dll" ) ]
    static extern bool DeleteDC ( IntPtr hDC );

    [ DllImport ( "gdi32.dll" ) ]
    static extern bool DeleteObject ( IntPtr hObject );

    [ DllImport ( "user32.dll" ) ]
    static extern IntPtr GetWindowDC ( IntPtr hWnd );

    [ DllImport ( "user32.dll" ) ]
    static extern IntPtr GetWindowRect (     IntPtr hWnd, 
                                         ref RECT rect );

    [ DllImport ( "user32.dll" ) ]
    static extern IntPtr ReleaseDC ( IntPtr hWnd, 
                                     IntPtr hDC );

    [ DllImport ( "gdi32.dll" ) ]
    static extern IntPtr SelectObject ( IntPtr hDC, 
                                        IntPtr hObject );


    // ************************************************** window_image

    /// <summary>
    /// obtains the image of the desktop window with the given handle
    /// </summary>
    /// <param name="handle">
    /// handle to the window
    /// </param>
    /// <returns>
    /// if successful, image of the window whose handle was passed; 
    /// otherwise, null
    /// </returns>
    public static Image window_image ( IntPtr handle )
        {
        IntPtr  hBitmap = IntPtr.Zero;
        IntPtr  hdcDest = IntPtr.Zero;
        IntPtr  hdcSrc = IntPtr.Zero;
        IntPtr  hOld = IntPtr.Zero;
        int     height = 0;
        Image   image = null;
        int     width = 0;
        RECT    windowRect;

        try
            {
                                        // get the hDC of the window 
            hdcSrc = GetWindowDC ( handle );
                                        // get the size
            windowRect = new RECT ( );
            GetWindowRect ( handle, ref windowRect );
            width = windowRect.right - windowRect.left;
            height = windowRect.bottom - windowRect.top;
                                        // create a device context to 
                                        // which we can copy
            hdcDest = CreateCompatibleDC ( hdcSrc );
                                        // create a bitmap to which we 
                                        // can copy
            hBitmap = CreateCompatibleBitmap ( hdcSrc, 
                                               width, 
                                               height );
                                        // select the bitmap object
            hOld = SelectObject ( hdcDest, hBitmap );
                                        // bitblt the image
            BitBlt ( hdcDest,
                     0,
                     0,
                     width,
                     height,
                     hdcSrc,
                     0,
                     0,
                     SRCCOPY );
                                        // restore selection
            SelectObject ( hdcDest, hOld );
                                        // get the .NET image object
            image = Image.FromHbitmap ( hBitmap );
            }
        catch
            {
            image = null;
            }
        finally
            {
                                        // clean up 
            if ( hdcDest != IntPtr.Zero );
                {
                DeleteDC ( hdcDest );
                }
            if ( hdcSrc != IntPtr.Zero )
                {
                ReleaseDC ( handle, hdcSrc );
                }
            if ( hBitmap != IntPtr.Zero )
                {
                DeleteObject ( hBitmap );
                }
            }

        return ( image );
        }

    // ****************************************** capture_window_image

    /// <summary>
    /// obtains the image of the desktop window with the given title
    /// </summary>
    /// <param name="title">
    /// string containing the title of the window
    /// </param>
    /// <returns>
    /// if successful, image of the window whose title was passed; 
    /// otherwise, null
    /// </returns>
    public static Image capture_window_image ( string title )
        {
        Image   image = null;
        IntPtr  window_handle = IntPtr.Zero;
                                        // get window handle
        foreach ( Process process in Process.GetProcesses ( ) )
            {
            if ( process.MainWindowTitle.
                         ToLower ( ).
                         Trim ( ).
                         StartsWith ( title.ToLower ( ).
                                            Trim ( ) ) )
               {
               window_handle = process.MainWindowHandle;
               break;
               }
            }

        if ( window_handle != IntPtr.Zero )
            {
            image = window_image ( window_handle );
            }

        return ( image );
        }

    } // class CaptureDesktopWindow


It is invoked by


C#
Image   image = CaptureDesktopWindow.capture_window_image ( "Dynamic Update" );


In this case, there is a window titled "Dynamic Update" on the desktop.



Hope that helps.

 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900