Overview is that this is a project for remote support, like Teamviewer. I have a broker, client and technician app.
Currently the client app takes a screenshot and sends it to the broker. The broker realises its a screenshot and sends it to the relevant technician client that authenticated prior.
Technician client then receives the image from the broker and displays it in a picturebox at the Technician end.
Issue is that when the screenshot is sent and displayed once, the client crashes, but i'm not getting any kind of exception so i'm lost and looking for help. I expect it's something stupid / simple, but i cannot see what.
Image Example - You will see client is connected to the broker in the Technician app, but on the broker app it has crashed and vanished.
[
^]
Below is the relevant code:
Client:
Note: I also get the amount of screens and current screen resolution and send with the screenshot for use at the technician end.
private int ScreenToView = 0;
private bool SendMyScreen = false;
private bool ShowCursor = false;
public void SendScreen( )
{
int NumOfScreens = 0;
while( SendMyScreen )
{
try
{
Bitmap bmpScreenshot = new Bitmap( Screen.AllScreens[ ScreenToView ].Bounds.Width, Screen.AllScreens[ ScreenToView ].Bounds.Height, PixelFormat.Format16bppRgb555 );
using Graphics gfxScreenshot = Graphics.FromImage( bmpScreenshot );
gfxScreenshot.CopyFromScreen( Screen.AllScreens[ ScreenToView ].Bounds.X, Screen.AllScreens[ ScreenToView ].Bounds.Y, 0, 0, Screen.AllScreens[ ScreenToView ].Bounds.Size, CopyPixelOperation.SourceCopy );
if( ShowCursor )
{
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf( typeof( CURSORINFO ) );
if( GetCursorInfo( out pci ) )
{
DrawIcon( gfxScreenshot.GetHdc( ), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor );
gfxScreenshot.ReleaseHdc( );
}
}
using MemoryStream ms = new MemoryStream( );
bmpScreenshot.Save( ms, ImageFormat.Jpeg );
byte[ ] ssBuffer = new byte[ ms.Length + 11 ];
ssBuffer[ 0 ] = 2;
foreach( Screen screen in Screen.AllScreens ) { NumOfScreens++; }
Array.Copy( BitConverter.GetBytes( NumOfScreens ), 0, ssBuffer, 1, 1 );
Array.Copy( BitConverter.GetBytes( Screen.AllScreens[ ScreenToView ].Bounds.Width ), 0, ssBuffer, 2, 4 );
Array.Copy( BitConverter.GetBytes( Screen.AllScreens[ ScreenToView ].Bounds.Height ), 0, ssBuffer, 6, 4 );
Array.Copy( ms.ToArray( ), 0, ssBuffer, 10, ms.Length );
BrokerSocket.Send( ssBuffer, Convert.ToInt32( ms.Length + 10 ), SocketFlags.None );
NumOfScreens = 0;
Thread.Sleep( 100 );
}
catch( Exception e )
{
DebugLog( "SendScreen Exception: " + e.Message.ToString( ) );
}
}
}
Broker:
public void SendDataToTechnician( Socket clientSocket, byte[ ] data, int bytesRead )
{
try
{
if( Success.technicianSocket != null && Success.technicianSocket.Connected )
{
Success.technicianSocket.Send( data );
}
}
catch( Exception ex ) { DebugLog( "SendDataToTechnician Exception: " + ex.Message.ToString( ) ); }
}
Technician:
public void ShowClientScreen( byte[ ] data, int dataRead )
{
try
{
byte[ ] imgData = new byte[ dataRead ];
byte[ ] NumOfScreens = new byte[ 4 ]; Array.Copy( data, 1, NumOfScreens, 0, 1 );
Remote_Num_Of_Screens = BitConverter.ToInt32( NumOfScreens, 0 );
byte[ ] ScreenW = new byte[ 4 ]; Array.Copy( data, 2, ScreenW, 0, 4 );
byte[ ] ScreenH = new byte[ 4 ]; Array.Copy( data, 6, ScreenH, 0, 4 );
Remote_Screen_Width = BitConverter.ToInt32( ScreenW, 0 );
Remote_Screen_Height = BitConverter.ToInt32( ScreenH, 0 );
Array.Copy( data, 10, imgData, 0, dataRead -9 );
using MemoryStream ms = new MemoryStream( imgData );
Image RecvImage = Image.FromStream( ms );
if( ScreenSize == PictureBoxSizeMode.StretchImage )
{
MethodInvoker ChangeScreenImageTypeStretch = delegate
{
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = RecvImage;
};
Invoke( ChangeScreenImageTypeStretch );
}
else if( ScreenSize == PictureBoxSizeMode.Normal )
{
MethodInvoker ChangeScreenImageTypeAutoSize = delegate
{
pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
pictureBox1.Image = RecvImage;
};
Invoke( ChangeScreenImageTypeAutoSize );
}
MethodInvoker UpdateScreenNumButton = delegate { btnScreenNum.Text = Remote_Screen_Num + 1 + "/" + Remote_Num_Of_Screens; };
Invoke( UpdateScreenNumButton );
}
catch( Exception ex )
{
DebugLog( "ShowClientScreen Exception: " + ex.Message.ToString( ) );
}
}
What I have tried:
I've logged the screenshot buffer which seems to be around 65535 so confirmed the buffer size if plenty.
Logged the information at the technician end and all seems fine