Getting messy/croped on PictureBox by Socket Streaming C# - c#

I am trying to get the printScreen from another device using socket.
My sending device (windowsce 6.0) code is
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Data;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace ServerComputer
{
class Program
{
static Socket sendsocket;
enum RasterOperation : uint { SRC_COPY = 0x00CC0020 }
[DllImport("coredll.dll")]
static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, RasterOperation rasterOperation);
[DllImport("coredll.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("coredll.dll")]
private static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
public static void Main(string[] args)
{
Console.Out.WriteLine("Gildo Lindo Fon");
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("192.168.0.24"), 81);
sendsocket.Connect(ipendpiont);
//Establishment of end point
Console.Out.WriteLine("starting thread");
Thread th = new Thread(sendImageThread);
//th.IsBackground = true;
th.Start();
}
catch (Exception ee)
{
Console.Out.WriteLine(ee.Message);
return;
}
}
private static Bitmap GetScreen()
{
Rectangle bounds = Screen.PrimaryScreen.Bounds;
IntPtr hdc = GetDC(IntPtr.Zero);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format16bppRgb565);
using (Graphics graphics = Graphics.FromImage(bitmap))
{
IntPtr dstHdc = graphics.GetHdc();
BitBlt(dstHdc, 0, 0, bounds.Width, bounds.Height, hdc, 0, 0,RasterOperation.SRC_COPY);
graphics.ReleaseHdc(dstHdc);
}
ReleaseDC(IntPtr.Zero, hdc);
return bitmap;
}
private static void sendImageThread()
{
Console.Out.WriteLine("SENDING");
while (true)
{
try
{
MemoryStream ms = new MemoryStream();
Bitmap bitmapScreen = GetScreen();
bitmapScreen.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); //Here I use the BMP format
bitmapScreen.Save(".\\printimg.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] b = ms.ToArray();
sendsocket.Send(b);
ms.Close();
}
catch (Exception ee)
{
Console.Out.WriteLine(ee.Message);
break;
}
Thread.Sleep(1000);
}
}
}
}
My receiver code is like this:
using System.Net;
using System.Net.Sockets;
namespace httpScreenClient;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Socket hostSocket = null!;
Thread thread = null!;
string localIP = string.Empty;
string computrHostName = string.Empty;
int dataSize = 0;
byte[] imageBytes = new byte[800 * 650 * 16*10]; //Picture of great 16 bpp RGB 565
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("192.168.0.24"), 81);
//Connection node
receiveSocket.Bind(hostIpEndPoint);
receiveSocket.Listen(10);
//MessageBox.Show("start");
hostSocket = receiveSocket.Accept();
thread = new Thread(new ThreadStart(trreadimage))
{
IsBackground = true
};
thread.Start();
}
private void trreadimage()
{
while (true) {
string imageName = "stremScreen.JPG";
try
{
dataSize = hostSocket.Receive(imageBytes);
if (dataSize > 0)
{
MemoryStream ms = new MemoryStream(imageBytes);
Image img = Image.FromStream(ms);
img.Save(imageName, System.Drawing.Imaging.ImageFormat.Jpeg);
videoBox.Image = img;
ms.Close();
}
}
catch (Exception ee)
{
//messagebox.show("foi aqui - " + ee.message);
break;
}
Thread.Sleep(1500);
}
trreadimage();
}
}
I checked the screenprinted saved on the sending side and is alright, but what I getting on the receiver side is very messy, as there was some wrongs crops one over the other...
Streamed image received:
Do you guys have any suggest about what could be going on? actually I was getting the Image.FromStream() error too (https://social.msdn.microsoft.com/Forums/en-US/820fe38b-3fb6-4490-9608-10c4133e4a50/imagefromstreamms-parameter-is-not-valid?forum=aspdotnetwebpages) on the receiver side, that's why I left the catch {} part of the code empty... I didn't get to solve this error.

After some tries I got the solution by compressing the byte array before sending with
private static byte[] Compress(byte[] data)
{
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionMode.Compress))
{
dstream.Write(data, 0, data.Length);
}
return output.ToArray();
}
And decompressing it on the other side with:
private static byte[] Decompress(byte[] data)
{
MemoryStream input = new MemoryStream(data);
MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
return output.ToArray();
}

Related

Decoding Z64 (ZB64) string

I'm working on breaking down ZPL label definitions generated by NiceLabel label making software. For the most part I don't have to worry about decoding the Z64 because it is just encoded graphics and I don't need to change the underlying data.
However I have a line of text that is used as a graphic by the label for some reason probably due to Font's or something.
Anyways, the Z64 or ZB64 string is created by compressing the original data using LZ77 and encoding that as Base64 and then appending a CRC at the end.
TEST STRING FULL EXAMPLE:
:Z64:eJztkDFOxDAQRb81hRsULmBtruECyRwpZYpFGLmg5AhwFKMUuYal9CtL26QwHsbe3RMguv3lz9P85wD3/CWaiZ+56OjqWA44cwKIAyfeXXL1sQ7YWqd54czltTge+VOdOQsXFp8TrLUw9KEW3+6pLU4Zk3mC0ataonSEzU8JMywGCiFcue+c8YLGvYcLF5a+68WFhbvtRs5jdmVkWolj96vgXe/it7eucT+0+gxV5N5RrdTveQpevhnxO+BEfRe0xIzc/EbUzkn3lhLSIH6DdFeu+c39Hb7c7vksfrJryB8vu6A4cxE/NjpK1/6LkJZ3+nL1gaLt3D33/Ed+AehfkrY=:6C38
TEST STRING TARGET EXAMPLE:
eJztkDFOxDAQRb81hRsULmBtruECyRwpZYpFGLmg5AhwFKMUuYal9CtL26QwHsbe3RMguv3lz9P85wD3/CWaiZ+56OjqWA44cwKIAyfeXXL1sQ7YWqd54czltTge+VOdOQsXFp8TrLUw9KEW3+6pLU4Zk3mC0ataonSEzU8JMywGCiFcue+c8YLGvYcLF5a+68WFhbvtRs5jdmVkWolj96vgXe/it7eucT+0+gxV5N5RrdTveQpevhnxO+BEfRe0xIzc/EbUzkn3lhLSIH6DdFeu+c39Hb7c7vksfrJryB8vu6A4cxE/NjpK1/6LkJZ3+nL1gaLt3D33/Ed+AehfkrY=
My Code to Decode / Decompress:
static string DecompressZb64(string compressedString)
{
var b64 = SmartWarehouse.Shared.Utils.Parser.ConvertFromBase64(compressedString);
var encoding = new ASCIIEncoding();
var inBytes = Encoding.ASCII.GetBytes(b64);
var outBytes = new byte[inBytes.Length];
try
{
using (var memoryStream = new MemoryStream())
using (var decompressionStream = new DeflateStream(memoryStream, CompressionMode.Decompress))
{
decompressionStream.Read(outBytes, 0, inBytes.Length);
}
return encoding.GetString(outBytes);
}
catch (Exception e)
{
// TODO: DOcument exception
Console.WriteLine(e.Message);
}
return string.Empty;
}
Current Exception:
Block length does not match with its complement.
Stacktrace:
at System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block)
at System.IO.Compression.Inflater.Decode()
at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
at SmartWarehouse.Tools.Program.DecompressZb64(String compressedString) in C:\Users\[user_dir]\Source\Repos\Handheld.[user].[fork]\SmartWarehouse.Tools\Program.cs:line 511
UPDATE:
I was looking into this and I found this SO post it is essentially the same issue. So i did some more research and i found this article on a blog from 2007. Which discusses a workaround by skipping the first 2 bytes in the input array due to those bytes not actually being included in the RFC specification.
CODE CHANGE:
static string DecompressZb64(string compressedString)
{
var b64 = Convert.FromBase64String(compressedString);
var encoding = new ASCIIEncoding();
var outBytes = new byte[b64.Length - 2];
try
{
using (var memoryStream = new MemoryStream(b64))
{
memoryStream.ReadByte();
memoryStream.ReadByte();
using (var decompressionStream = new DeflateStream(memoryStream, CompressionMode.Decompress))
{
decompressionStream.Read(outBytes, 0, b64.Length - 2);
}
}
return encoding.GetString(outBytes);
}
catch (Exception e)
{
// TODO: DOcument exception
Console.WriteLine(e.Message);
}
return string.Empty;
}
This code change doesn't actually produce an exception anymore however it doesn't decompress properly and returns this result:
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
That data looks fine to me, I got this image out of it:
It's a monochrome bitmap, one bit per pixel.
Your code didn't read until the end of the stream, there are actually 1280 bytes of image data, which can then be decoded to the image above.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace ZB64Decode
{
public class Program
{
static void Main(string[] args)
{
//this is C#
var sb = new StringBuilder();
sb.AppendLine("^XA");
sb.AppendLine("^UT1,1");
sb.AppendLine("^Uh0,300,64,4000,2,0,F");
sb.AppendLine("^Uh1,300,64,4000,2,0,F");
sb.AppendLine("^UC1,0,1,0,0");
sb.AppendLine("^LH0,0");
sb.AppendLine("^LT0");
sb.AppendLine("^XZ");
sb.AppendLine("^XA");
sb.AppendLine("^PW3543");
sb.AppendLine("^LL512");
sb.AppendLine("^FO532,66^GFA,885,9272,76,:Z64:eJztWkFywyAMDMOBI0/gKTyNPC1P6RN6zKFTNxiCY0AgJE0nh+zJTc0GrdYES1wu/wWzHfiVIuLR2YZpB4FJpZH38UcouP6oRHddogqPEd/9f0WyLzyTGqpsVuLUj5tvoxv8tv3gqSa3WCSZxrjIoMgUzpAGoxnW2wZMdIFHG9tOEhQtekVyze7VSzYMQ/3DVIMTRt/sFtcUA0epZ2o28GCUfi3CCOjbDWHVhMaElRyOB1nss3+C7no7rAqf4DsTM+vr+A7VUYw4rTixeqAmqdUf2bKjESrz96LGwlQWNxRvPVHNw1N+2p9wJ30UWfkIfbKT5YQY1X/5gxVinMqtXCui53vjWVmMCEcmHS/EGOT1ecnKYoQudlXra3ONIphZ3Oh14H7rCzrKdDxXrijYLV3w5Socmr50HcixCUhfNBeQvkxIQPoiVOA92AkqPdISacwsImnMSklyiVgiu8FyF6+EnUbEXjk8SS4Rq+YUviuXyCOUH6IP14er5npX37/rmiO5rkqu90K/Q5Jcux0Ud0OekCwvuZ+Q3OdI7r9EDJZJJPerkvtoiUQWY0m+d0i+Dwk4/5BJ8P2R++p+enk3XIf5I3uSdYDX93gKTnUEywvypLdmBVlVgwInk1U1iFUcqibCKVo1AjHqhc1Qanm1W2qsq5FouFZqS677diyw2r7LcL0Vnjax7rTgHsEQQC+CUsDvl+8vpMYCOGTQogEwaALBLZo+hk2gpRbYpM1llnLpx4V6fMsQ0TQM6KaAmQqisC1ijWiyahwZ7jZUVxfZIcb0m1F96x12dnzALRx9GHf8x6cFWmzwkQAPH2EA4AE26PMh0lmTagLkMye+HDG5P4+HUCbVsHGZIqqzMLPb/wCr2VTW:718B");
sb.AppendLine("^PQ1,0,1,Y^XZ");
var zpl = sb.ToString();
//extract the Z64-String
var z64Data = "";
var bytesPerRow = 0;
foreach (var item in zpl.Split('^'))
{
if (item.StartsWith("GFA"))
{
var sp= item.Split(':');
z64Data = item.Substring(sp[0].Length);
bytesPerRow = Convert.ToInt32(sp[0].Split(',')[3]);
break;
}
}
//convert String to Bitmap
Bitmap decodedBitmap = null;
if (z64Data.StartsWith(":Z64"))
{
var imageData = DecompressZb64(z64Data.Substring(5));
int width = bytesPerRow * 8;
int height = imageData.Length / bytesPerRow;
decodedBitmap = ArrayToBitmap(imageData, width, height, PixelFormat.Format1bppIndexed);
}
Debug.WriteLine(decodedBitmap.Width + ":" + decodedBitmap.Height);
}
public static Bitmap ArrayToBitmap(byte[] bytes, int width, int height, PixelFormat pixelFormat)
{
var image = new Bitmap(width, height, pixelFormat);
var imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, pixelFormat);
try
{
Marshal.Copy(bytes, 0, imageData.Scan0, bytes.Length);
}
finally
{
image.UnlockBits(imageData);
}
return image;
}
public static byte[] DecompressZb64(string compressedString)
{
var b64 = Convert.FromBase64String(compressedString.Split(':')[0]).Skip(2).ToArray();
return Decompress(b64);
}
public static byte[] Decompress(byte[] data)
{
byte[] decompressedArray = null;
try
{
using (MemoryStream decompressedStream = new MemoryStream())
{
using (MemoryStream compressStream = new MemoryStream(data))
{
using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);
}
}
decompressedArray = decompressedStream.ToArray();
}
}
catch (Exception ex)
{
// do something !
}
return decompressedArray;
}
}
}

Stream.Flush is not Flushing data in stream

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Sockets;
using InTheHand.Net.Ports;
using System.IO;
Guid muuid = new Guid("00001101-0000-1000-8000-00805F9B34FB");
private void scan()
{
UpdateUI("Starting Scan...");
BluetoothClient client = new BluetoothClient();
Devices = client.DiscoverDevicesInRange();
UpdateUI("Scan Complete");
foreach (BluetoothDeviceInfo d in Devices)
{
items.Add(d.DeviceName);
}
UpdateDeviceList();
}
private void StartScan()
{
lb_BT.DataSource = null;
lb_BT.Items.Clear();
items.Clear();
Thread bluetoothScanThread = new Thread(new ThreadStart(scan));
bluetoothScanThread.Start();
}
BluetoothDeviceInfo[] Devices;
private void UpdateDeviceList()
{
Func<int> del = delegate()
{
lb_BT.DataSource = items;
return 0;
};
Invoke(del);
}
BluetoothDeviceInfo deviceInfo;
private void ClientConnectThread()
{
BluetoothClient client = new BluetoothClient();
UpdateUI("Attempting connect");
client.BeginConnect(deviceInfo.DeviceAddress, muuid, this.BluetoothClientConnectCallback, client);
}
Stream stream = null;
public void BluetoothClientConnectCallback(IAsyncResult res)
{
{
BluetoothClient client = (BluetoothClient)res.AsyncState;
client.EndConnect(res);
stream = client.GetStream();
else
{
SetupObj.bInitialize(stream);
}
//fpcresp[0] = (byte)stream.ReadByte();
}
}
private void writeCmd(byte[] buffer)
{
try
{
stream.Flush();
stream.Write(buffer, 0, buffer.Length);
retCode = SUCCESS;
}
catch (Exception ex)
{
retCode = FAILURE;
Debug.WriteLine("Write IO Exception " + ex.Message);
}
}
private byte[] ReadCmd()
{
if( stream!= null)
{
byte[] BytesRead = new byte[100];
int BytesReadCnt = 0;
stream.Read(BytesRead, 0, 3);
return BytesRead;
}
else
{
return null;
}
}
First i will call writeCmd , then ReadCmd. Sometimes what is happening i am getting the unread data in ReadCmd.(because of last writeCmd) so i used stream.Flush(); before every writeCmd. then also the data on stream is not Flushing.

sending big file with socket to server c#

I'm trying to send a file about 250 kb to server but i have a corruption and it seemd that tottaly transfered some bytes only. The flow of command is
Write to stream: Send\r\n
Write to stream: FileName\r\n
Write to stream: FileData \r\n
Close the connection
Here is the code:
TcpClient sendClient = new TcpClient(serverName, port);
SslStream sendStream = new SslStream(sendClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sendStream.AuthenticateAsClient(serverName, null, SslProtocols.Ssl2, true);
sendStream.Write(Encoding.UTF8.GetBytes("Login\r\n" + username + "\r\n" + password + "\r\n"));
sendStream.Flush();
int bytesResp = -1;
byte[] buffer = new byte[1026];
bytesResp = sendStream.Read(buffer, 0, buffer.Length);
string response = Encoding.UTF8.GetString(buffer, 0, bytesResp);
if (response.Trim() == "OK")
{
byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName + "\r\n");
byte[] fileData = File.ReadAllBytes(filePath);
byte[] newLine = Encoding.ASCII.GetBytes("\r\n");
byte[] clientData = new byte[4 + Encoding.ASCII.GetBytes("Send\r\n").Length + fileNameByte.Length + fileData.Length+newLine.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
byte[] send = Encoding.ASCII.GetBytes("Send\r\n");
send.CopyTo(clientData, 0);
fileNameLen.CopyTo(clientData, 4 + send.Length);
fileNameByte.CopyTo(clientData, send.Length);
fileData.CopyTo(clientData, 4 + fileNameByte.Length + send.Length);
newLine.CopyTo(clientData, 4+ fileNameByte.Length + send.Length + fileData.Length);
MessageBox.Show(clientData.Length.ToString());
sendStream.Write(clientData, 0, clientData.Length);
sendStream.Flush();
sendStream.Write(Encoding.UTF8.GetBytes("Quit\r\n"));
sendClient.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Does anybody have an idea please?
You haven't told us about the other end of the connection, so this answer is partially speculative...
BitConverter.GetBytes(fileNameByte.Length); is likely to be a little-endian conversion.
Almost all network encoding will be big-endian, so this is a strong candidate for the failure.
I suggest you use the EndianBitConverter.Big converter from Jon Skeet's miscutil to get the proper encoding order.
I send file up to 1GB with this code
Server Code
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace Server_FileSend
{
public partial class Form1 : Form
{
Socket Server = null;
Socket Client = null;
Thread trStart;
Thread trRecive;
const int sizeByte = 1024;
public Form1()
{
InitializeComponent();
}
private void ReciveFile()
{
while (true)
{
try
{
byte[] b = new byte[sizeByte];
int rec = 1;
int vp = 0;
rec = Client.Receive(b);
int index;
for (index = 0; index < b.Length; index++)
if (b[index] == 63)
break;
string[] fInfo = Encoding.UTF8.GetString(b.Take(index).ToArray()).Split(':');
this.Invoke((MethodInvoker)delegate
{
progressBar1.Maximum = int.Parse(fInfo[0]);
});
string path = Application.StartupPath + "\\Downloads\\";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
FileStream fs = new FileStream(path + fInfo[1], FileMode.Append, FileAccess.Write);
string strEnd;
while (true)
{
rec = Client.Receive(b);
vp = vp + rec;
strEnd = ((char)b[0]).ToString() + ((char)b[1]).ToString() + ((char)b[2]).ToString() + ((char)b[3]).ToString() + ((char)b[4]).ToString() + ((char)b[5]).ToString();
if (strEnd == "!endf!")
{
fs.Flush();
fs.Close();
MessageBox.Show("Receive File " + ((float)(float.Parse(fInfo[0]) / 1024)).ToString() + " KB");
break;
}
fs.Write(b, 0, rec);
this.Invoke((MethodInvoker)delegate
{
progressBar1.Value = vp;
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
Form1_FormClosing(null, null);
}
}
}
private void StartSocket()
{
Server.Listen(1);
Client = Server.Accept();
trRecive = new Thread(new ThreadStart(ReciveFile));
trRecive.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint IP = new IPEndPoint(IPAddress.Any, 5050);
Server.Bind(IP);
trStart = new Thread(new ThreadStart(StartSocket));
trStart.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
trRecive.Abort();
trStart.Abort();
Environment.Exit(Environment.ExitCode);
}
catch (Exception)
{
Environment.Exit(Environment.ExitCode);
}
}
}
}
Client Code
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Clienf_fileSend
{
public partial class Form1 : Form
{
Socket Client = null;
Thread trRecive;
const int sizeByte = 1024;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint IP = new IPEndPoint(IPAddress.Parse(textBox1.Text), 5050);
Client.Connect(IP);
button1.Enabled = false;
button2.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void SendFile(object FName)
{
try
{
FileInfo inf = new FileInfo((string)FName);
progressBar1.Invoke((MethodInvoker)delegate
{
progressBar1.Maximum = (int)inf.Length;
progressBar1.Value = 0;
});
FileStream f = new FileStream((string)FName, FileMode.Open);
byte[] fsize = Encoding.UTF8.GetBytes(inf.Length.ToString() + ":");
byte[] fname = Encoding.UTF8.GetBytes(inf.Name + "?");
byte[] fInfo = new byte[sizeByte];
fsize.CopyTo(fInfo, 0);
fname.CopyTo(fInfo, fsize.Length);
Client.Send(fInfo);
if (sizeByte> f.Length)
{
byte[] b = new byte[f.Length];
f.Seek(0, SeekOrigin.Begin);
f.Read(b, 0, (int)f.Length);
Client.Send(b);
}
else
{
for (int i = 0; i < (f.Length - sizeByte); i = i + sizeByte)
{
byte[] b = new byte[sizeByte];
f.Seek(i, SeekOrigin.Begin);
f.Read(b, 0, b.Length);
Client.Send(b);
progressBar1.Invoke((MethodInvoker)delegate
{
progressBar1.Value = i;
});
if (i + sizeByte >= f.Length - sizeByte)
{
progressBar1.Invoke((MethodInvoker)delegate
{
progressBar1.Value = (int)f.Length;
});
int ind = (int)f.Length - (i + sizeByte);
byte[] ed = new byte[ind];
f.Seek(i + sizeByte, SeekOrigin.Begin);
f.Read(ed, 0, ed.Length);
Client.Send(ed);
}
}
}
f.Close();
Thread.Sleep(1000);
Client.Send(Encoding.UTF8.GetBytes("!endf!"));
Thread.Sleep(1000);
MessageBox.Show("Send File " + ((float)inf.Length / 1024).ToString() + " KB");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog fdl = new OpenFileDialog();
if (fdl.ShowDialog() == DialogResult.OK)
{
trRecive = new Thread(new ParameterizedThreadStart(SendFile));
trRecive.Start(fdl.FileName);
}
fdl = null;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
trRecive.Abort();
Environment.Exit(Environment.ExitCode);
}
catch (Exception)
{
Environment.Exit(Environment.ExitCode);
}
}
}
}

Program can only send scaled images over the internet

I did program a tcp/ip-chat, which has functions like webcam-chat and screentransfer and something like that.
But the problem is, that it only can receive pictures which size is scaled ...
I will poste the full code of my test-class:
//static Byte[] Ip = {
// 192,
// 168,
// 0,
// 215q
// };
//static IPAddress IpAdress = new IPAddress(Ip);
TcpListener sTCP = new TcpListener(IPAddress.Any, 8000);
TcpClient cTCP;
Byte[] ImageData;
String IP = null;
Int32 Port = 0;
private void close(object sender, FormClosingEventArgs e)
{
sTCP.Stop();
Environment.Exit(Environment.ExitCode);
}
private void Form1_Load(object sender, EventArgs e)
{
Thread listthread = new Thread(new ThreadStart(StartListening));
listthread.Start();
Thread startReceiving = new Thread(new ThreadStart(Listen));
startReceiving.Start();
}
void StartListening()
{
sTCP.Start();
//9123
}
void startsendwebcam(Bitmap img)
{
byte[] s;
byte[] buffer;
cTCP = new TcpClient(IP, Port);
BinaryWriter sWriter = new BinaryWriter(cTCP.GetStream());
buffer = Image2ByteArray(img, System.Drawing.Imaging.ImageFormat.Png);
int cLength = buffer.Length;
s = new byte[cLength];
s = buffer;
sWriter.Write(cLength);
sWriter.Write(s);
sWriter.Flush();
sWriter.Close();
}
private void button1_Click(object sender, EventArgs e)
{
if (timer1.Enabled)
{
button3.Text = "Begin";
textBox1.Enabled = true;
timer1.Enabled = false;
}
else
{
String[] split = textBox1.Text.Split(':');
IP = split[0];
Port = Convert.ToInt32(split[1]);
button3.Text = "End";
textBox1.Enabled = false;
timer1.Enabled = true;
}
}
private Bitmap CreateScreenshot(int left, int top, int width, int height)
{
Bitmap bmp = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(left, top, 0, 0, new Size(width, height));
g.Dispose();
return bmp;
}
Bitmap ResizeImage(Bitmap imgToResize, Size size)
{
Bitmap b = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage((Image)b))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, size.Width, size.Height);
}
return b;
}
void Listen()
{
do
{
try
{
if (sTCP.Pending())
{
cTCP = sTCP.AcceptTcpClient();
BinaryReader r = new BinaryReader(cTCP.GetStream());
ImageData = new Byte[r.ReadInt32()];
ImageData = r.ReadBytes(ImageData.Length);
pictureBox1.Image = ByteArray2Image(ImageData);
r.Close();
}
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}
while (true);
}
public byte[] Image2ByteArray(Image Bild, System.Drawing.Imaging.ImageFormat Bildformat)
{
System.IO.MemoryStream MS = new System.IO.MemoryStream();
Bild.Save(MS, Bildformat);
MS.Flush();
return MS.ToArray();
}
public Image ByteArray2Image(byte[] ByAr)
{
Image img = default(Image);
System.IO.MemoryStream MS = new System.IO.MemoryStream(ByAr);
return Image.FromStream(MS);
}
private void timer1_Tick(object sender, EventArgs e)
{
int quality = trackBar1.Value * 10;
if (quality != 0)
{
startsendwebcam(ResizeImage(CreateScreenshot(0, 0, 800, 800), new Size(quality, quality)));
}
}
}
I can send and receive images over the internet; i did portforwarding;
but it can only receive scaled images.
Is there an possibility to send and receive HD-Pictures?
The current result is;
http://www.directupload.net/file/d/3719/9sel75ej_png.htm
Yay!
I got it!
It can send now a picture with dimensions over 800 over wan!
The server is still with bugs, if anyone is interrested about TCPImageSending I can fix the server...
http://ageofadventure.bplaced.net/WORKING.png
The project:
http://ageofadventure.bplaced.net/TCPIPImageClass.zip
Have fun!

Show only small part of picture

I have write a program that consists server and client. The server makes a screenshot desktop, and the client receives the screenshot and shows on the form. There is a problem in the data transfer, I see only a small strip. I checked before sending the image on the server is ok. However, the client receives the wrong image. What is wrong?
XAML:
<Window x:Class="TestTCP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestTCP" Height="350" Width="525">
<Grid>
<Image x:Name="img1" Margin="0"/>
</Grid>
</Window>
Code C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Task rec = new Task(WaitClientQuery);
rec.Start();
Task tk = new Task(Send);
tk.Start();
}
private void Send()//server part. take screen and send image
{
Bitmap temp = CaptureScreen(true);
MemoryStream ms3 = new MemoryStream();
BitmapImage image = new BitmapImage();
byte[] img_byte;
try
{
((System.Drawing.Bitmap)temp).Save(ms3, System.Drawing.Imaging.ImageFormat.Bmp);
image.BeginInit();
ms3.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms3;
image.EndInit();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
img_byte = ms.ToArray();
}
try
{
TcpClient client = new TcpClient("192.168.1.64", 4444);
NetworkStream netstream = client.GetStream();
netstream.Write(img_byte, 0, img_byte.Length);
netstream.Close();
client.Close();
}
catch (Exception)
{
}
}
catch (Exception ee)
{
}
}
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
struct POINTAPI
{
public int x;
public int y;
}
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
const Int32 CURSOR_SHOWING = 0x00000001;
public static Bitmap CaptureScreen(bool CaptureMouse)
{
Bitmap result = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
try
{
using (Graphics g = Graphics.FromImage(result))
{
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
if (CaptureMouse)
{
CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor);
g.ReleaseHdc();
}
}
}
}
}
catch
{
result = null;
}
return result;
}
void WaitClientQuery()//receive data(client)
{
try
{
IPAddress ip ;
IPAddress.TryParse("192.168.1.64", out ip);
TcpListener listener = new TcpListener(ip, 4444);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
Thread thread = new Thread(new ParameterizedThreadStart(ReadMessage));
thread.IsBackground = true;
thread.Start(client);
}
}
catch (Exception ex)
{
}
}
void ReadMessage(object obj)
{
try
{
TcpClient client = (TcpClient)obj;
NetworkStream netstream = client.GetStream();
byte[] arr = new byte[client.ReceiveBufferSize ];
int len = netstream.Read(arr, 0, client.ReceiveBufferSize);
if (len > 0)
{
try
{
Action act = delegate
{
MemoryStream strmImg = new MemoryStream(arr);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.EndInit();
img1.Source = myBitmapImage;
};
this.Dispatcher.BeginInvoke(act);
}
catch (Exception ex)
{
string message = ex.Message;
}
}
netstream.Close();
client.Close();
}
catch (Exception ex)
{
}
}
}
P.S. Result, screen program after compile:
click to view
The main root cause the client.ReceiveBufferSize using default value are 8192 byte so the client will not receive enough image which has been transferred from server. In my code, I would like to see at client receive correctly the size of image so I use BinaryWriter to transfer length of image. From client side I have used BinaryReader to read exactly number of bytes and size of image to save bandwidth. Hope this help
At the Send method:
TcpClient client = new TcpClient("192.168.1.64", 4444);
using (NetworkStream netstream = client.GetStream())
{
using (BinaryWriter bw = new BinaryWriter(netstream))
{
bw.Write(img_byte.Length);
bw.Write(img_byte, 0, img_byte.Length);
}
client.Close();
}
At the ReadMessage(object obj)
private void ReadMessage(object obj)
{
try
{
byte[] arr = null;
TcpClient client = (TcpClient) obj;
using (NetworkStream netstream = client.GetStream())
{
using (BinaryReader br = new BinaryReader(netstream))
{
var arrLen = new byte[4];
br.Read(arrLen, 0, 4);
int len = BitConverter.ToInt32(arrLen, 0);
if (len > 0)
{
arr = new byte[len];
int read = 0;
while (read != len)
{
read += br.Read(arr, read, arr.Length - read);
}
}
}
}
if (arr != null && arr.Length > 0)
{
try
{
Action act = delegate
{
MemoryStream strmImg = new MemoryStream(arr);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.EndInit();
img1.Source = myBitmapImage;
};
this.Dispatcher.BeginInvoke(act);
}
catch (Exception ex)
{
string message = ex.Message;
}
}
client.Close();
}
catch (Exception ex)
{
}
}
I expect client.ReceiveBufferSize on client side has wrong information
I would recomend to read data in loop.
if(netstream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = netstream.Read(myReadBuffer, 0, myReadBuffer.Length);
}
while(netstream.DataAvailable);
}
and save data into the List or memorystream
Or may be easier way, before your server send all data, send the size
netstream.Write(img_byte.Length); //does not work with NetworkStream
netstream.Write(img_byte, 0, img_byte.Length);
and client can read it first to allocate appropriate buffer.
To send and receive particular data type I would recomend
build BinaryWriter from your NetworkStream
using (BinaryWriter writer = new BinaryWriter(netstream))

Categories