One major tcp/ip headache
-
Hello everyone, I have a problem that I have been banging my head against the wall for the past few days trying to figure out...I am writing a remote assistance service and I want to send a file(a .jpg) using tcp/ip blocking sockets. I have used MANY other peoples source code, but still the file never arrives or I get ugly unhandled exceptions...I finally found one that sort of works...It sends a snapshot of the users screen ONE time, after that the client gives me a "connection reset by software on your remote host", I have included the client and server methods that are running in a seperate continuous thread...your help is MUCH appreciated. P.S. sorry for the bad formatting. <---Client source snippet---> public static void BeginSnapShotSend() { ScreenCapture SC = new ScreenCapture(); try { // get the remote IP address... IPHostEntry IPHost = Dns.Resolve("localhost"); IPAddress[] ip = IPHost.AddressList; int iPortNo = System.Convert.ToInt32(443); //create the end point IPEndPoint ipEnd = new IPEndPoint (ip[0],iPortNo); //connect to the remote host... PicConnect.Connect ( ipEnd ); nfs = new NetworkStream(PicConnect) ; } catch (SocketException SE) { System.Windows.Forms.MessageBox.Show(SE.ToString()); return; } while (true) { SC.CaptureScreenToFile("sc.jpg", ImageFormat.Jpeg); Thread.Sleep(1000); try { FileStream fin = new FileStream("sc.jpg",FileMode.Open , FileAccess.Read) ; //Get the Length of the file requested //and set various variables long total=fin.Length; long rdby=0; int len=0; byte[] buffed = new byte[4096]; //Open the file requested for download //One way of transfer over sockets is Using a NetworkStream //It provides some useful ways to transfer data byte[] m_sbuf = System.Text.Encoding.UTF8.GetBytes("fsize"+" "+total.ToString()); PicConnect.Send(m_sbuf); Thread.Sleep(1000); //lock the Thread here while(rdby
-
Hello everyone, I have a problem that I have been banging my head against the wall for the past few days trying to figure out...I am writing a remote assistance service and I want to send a file(a .jpg) using tcp/ip blocking sockets. I have used MANY other peoples source code, but still the file never arrives or I get ugly unhandled exceptions...I finally found one that sort of works...It sends a snapshot of the users screen ONE time, after that the client gives me a "connection reset by software on your remote host", I have included the client and server methods that are running in a seperate continuous thread...your help is MUCH appreciated. P.S. sorry for the bad formatting. <---Client source snippet---> public static void BeginSnapShotSend() { ScreenCapture SC = new ScreenCapture(); try { // get the remote IP address... IPHostEntry IPHost = Dns.Resolve("localhost"); IPAddress[] ip = IPHost.AddressList; int iPortNo = System.Convert.ToInt32(443); //create the end point IPEndPoint ipEnd = new IPEndPoint (ip[0],iPortNo); //connect to the remote host... PicConnect.Connect ( ipEnd ); nfs = new NetworkStream(PicConnect) ; } catch (SocketException SE) { System.Windows.Forms.MessageBox.Show(SE.ToString()); return; } while (true) { SC.CaptureScreenToFile("sc.jpg", ImageFormat.Jpeg); Thread.Sleep(1000); try { FileStream fin = new FileStream("sc.jpg",FileMode.Open , FileAccess.Read) ; //Get the Length of the file requested //and set various variables long total=fin.Length; long rdby=0; int len=0; byte[] buffed = new byte[4096]; //Open the file requested for download //One way of transfer over sockets is Using a NetworkStream //It provides some useful ways to transfer data byte[] m_sbuf = System.Text.Encoding.UTF8.GetBytes("fsize"+" "+total.ToString()); PicConnect.Send(m_sbuf); Thread.Sleep(1000); //lock the Thread here while(rdby
I have yet to figure out what everyone's infatuation with writing a VNC-like application in C# is. This is really not a good idea, mind you. Not only are there already clients that do this installed in Windows (NetMeeting is standard in Win98 and Win2K and newer, or some form of it; Windows XP already has remote assistance that's very flexible) but you can even use some of the APIs like NetMeeting to integrate into your own application. The true remote desktops don't use an entire screenshot, but a virtual frame buffer. Consider this: when a region is invalidated in Windows, it sends the
WM_PAINT
message with anHRGN
that specifies what needs to be repainted (in .NET, this corresponds to thePaint
event and thePaintEventArgs.ClipRectangle
property). This may be an entire window or just a portion of it. But the entire screen is not drawn each time. By using a virtual frame buffer you take advantage of this (requiring much less bandwidth). Only the bits for the newly drawn portion are transferred across the wire. It's this approach - if you're intent on reinventing the wheel (there's lots of "wheels" already, many very heavily tested) - you should look into. Unfortunately, .NET is too high level for such a task. Even if you do manage to P/Invoke all the native APIs you'll need an declare all the structs and consts, you'll incur performance penalties because of marshaling. You could, of course, write a Managed C++ assembly that alliviate most of these problems (mixing unmanaged and managed code to make such functionality accessible to other .NET assemblies written in any language). What you're currently doing will have problems like you're seeing. Far too much bandwidth is required and will most likely require more time to transfer than your current refresh time, creating a large bottleneck that won't go away and will eventually cause timeouts (pretty quickly). The more lag on the wire, the faster timeouts will start occuring.Microsoft MVP, Visual C# My Articles
-
I have yet to figure out what everyone's infatuation with writing a VNC-like application in C# is. This is really not a good idea, mind you. Not only are there already clients that do this installed in Windows (NetMeeting is standard in Win98 and Win2K and newer, or some form of it; Windows XP already has remote assistance that's very flexible) but you can even use some of the APIs like NetMeeting to integrate into your own application. The true remote desktops don't use an entire screenshot, but a virtual frame buffer. Consider this: when a region is invalidated in Windows, it sends the
WM_PAINT
message with anHRGN
that specifies what needs to be repainted (in .NET, this corresponds to thePaint
event and thePaintEventArgs.ClipRectangle
property). This may be an entire window or just a portion of it. But the entire screen is not drawn each time. By using a virtual frame buffer you take advantage of this (requiring much less bandwidth). Only the bits for the newly drawn portion are transferred across the wire. It's this approach - if you're intent on reinventing the wheel (there's lots of "wheels" already, many very heavily tested) - you should look into. Unfortunately, .NET is too high level for such a task. Even if you do manage to P/Invoke all the native APIs you'll need an declare all the structs and consts, you'll incur performance penalties because of marshaling. You could, of course, write a Managed C++ assembly that alliviate most of these problems (mixing unmanaged and managed code to make such functionality accessible to other .NET assemblies written in any language). What you're currently doing will have problems like you're seeing. Far too much bandwidth is required and will most likely require more time to transfer than your current refresh time, creating a large bottleneck that won't go away and will eventually cause timeouts (pretty quickly). The more lag on the wire, the faster timeouts will start occuring.Microsoft MVP, Visual C# My Articles
wow, ok thanks for your help. I totally forgot about using netmeeting, and I didn't truly realize how difficult such a thing could be.