Below I attached a segment of code I have in my server. It is the main segment that controls all incoming client messages. Some messages are just strings where others are images. It works sometimes but other times the while loop (will label) will break before the whole image is done.
I am not sure if there is a better way to detect what is being sent over because at the moment I have it just looking for key words to see if it's an image.
Main issue isn't how to detect if incoming bytes are images because it seems to not be a problem search for words like PNG and such... the main concern is the permature breaking of the while loop indicated below
Also I noted that the while loop performs normally on my laptop and not my desktop for one reason or another. Might be a fuke but I am not sure if this statement is useful.
if (stream.DataAvailable)
{
Task DataInterpetTask = Task.Factory.StartNew(() =>
{
byte[] buffer = new byte[0];
byte[] tbuffer;
int rLength, prevLength;
byte[] buf = new byte[c.getClientSocket().ReceiveBufferSize];
//below is the while loop that breaks early
while (stream.DataAvailable)
{
rLength = stream.Read(buf, 0, buf.Length);
if (rLength < buf.Length)
{
byte[] temp = new byte[rLength];
Array.Copy(buf, temp, rLength);
buf = temp;
}
prevLength = buffer.Length;
tbuffer = buffer;
buffer = new byte[buffer.Length + rLength];
Array.Copy(tbuffer, buffer, tbuffer.Length);
buf.CopyTo(buffer, prevLength);
MainWindow.mainWindowDispacter.BeginInvoke(PrintDebugLog, new Object[] { "prevLength : " + prevLength + " new Length: " + buffer.Length });
}
// below searches for image related key words seems to work but if loop above
//break early I only get part of an image
String msg = Encoding.ASCII.GetString(buffer);
if (msg.Contains("PNG") || msg.Contains("RBG") || msg.Contains("HDR"))
{
RowContainer tempContainer;
if ((tempContainer = MainWindow.mainWindow.RowExists(c)) != null)
{
tempContainer.Image = buffer;
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
MainWindow.mainWindow.UpdateRowContainer(tempContainer, 0)));
}
else
{
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
MainWindow.mainWindow.CreateClientRowContainer(c, buffer)));
}
return;
}
if (msg.Length < 4)
return;
// The rest of the image is handle here like its some sort of string message...
String switchString = msg.Substring(0, 4);
if (msg.Length > 4)
msg = msg.Substring(4);
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
{
if (MainWindow.debugWindow != null)
MainWindow.debugWindow.LogTextBox.AppendText("Received message " + msg + " from client: " + c.getClientIp() + " as a " + switchString + " type" + Environment.NewLine);
}));
switch (switchString)
{
case "pong":
c.RespondedPong();
break;
case "stat":
RowContainer tContain = MainWindow.mainWindow.RowExists(c);
if (tContain == null)
break;
tContain.SetState(msg);
MainWindow.mainWindow.UpdateRowContainer(tContain, 1);
break;
}
});
}
}
Here is some updated code that works for those who need to understand it.
Server side:
if (stream.DataAvailable)
{
Task DataInterpetTask = Task.Factory.StartNew(() =>
{
int totalBuffer, totalRecieved = 0;
byte[] totalBufferByte = new byte[4];
byte[] buffer = new byte[0];
byte[] tbuffer;
int rLength, prevLength;
byte[] buf = new byte[c.getClientSocket().ReceiveBufferSize];
stream.Read(totalBufferByte, 0, 4);
totalBuffer = BitConverter.ToInt32(totalBufferByte, 0);
totalBuffer = totalBuffer - 3;
while (totalBuffer > totalRecieved)
{
rLength = stream.Read(buf, 0, buf.Length);
totalRecieved = rLength + totalRecieved;
if (rLength < buf.Length)
{
byte[] temp = new byte[rLength];
Array.Copy(buf, temp, rLength);
buf = temp;
}
prevLength = buffer.Length;
tbuffer = buffer;
buffer = new byte[buffer.Length + rLength];
Array.Copy(tbuffer, buffer, tbuffer.Length);
buf.CopyTo(buffer, prevLength);
}
String msg = Encoding.ASCII.GetString(buffer);
if (msg.Contains("PNG") || msg.Contains("RBG") || msg.Contains("HDR"))
{
RowContainer tempContainer;
if ((tempContainer = MainWindow.mainWindow.RowExists(c)) != null)
{
tempContainer.Image = buffer;
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
MainWindow.mainWindow.UpdateRowContainer(tempContainer, 0)));
}
else
{
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
MainWindow.mainWindow.CreateClientRowContainer(c, buffer)));
}
return;
}
String switchString = msg.Substring(0, 4);
if (msg.Length > 4)
msg = msg.Substring(4);
MainWindow.mainWindowDispacter.BeginInvoke(new Action(() =>
{
if (MainWindow.debugWindow != null)
MainWindow.debugWindow.LogTextBox.AppendText("Received message " + msg + " from client: " + c.getClientIp() + " as a " + switchString + " type" + Environment.NewLine);
}));
switch (switchString)
{
case "pong":
c.RespondedPong();
break;
case "stat":
RowContainer tContain = MainWindow.mainWindow.RowExists(c);
if (tContain == null)
break;
tContain.SetState(msg);
MainWindow.mainWindow.UpdateRowContainer(tContain, 1);
break;
}
});
}
}
Client side:
public void SendResponse(int command, Object[] args)
{
if (ClientSocket == null)
{
Console.WriteLine("Command: ClientSocket");
return;
}
var serverStream = this.ClientSocket.GetStream();
if (!serverStream.CanRead || !serverStream.CanWrite)
{
Console.WriteLine("Command: serverStream Error");
return;
}
byte[] toSend = null;
switch (command)
{
// 0 - genneral, 1 - handshake response
case 0:
toSend = Encoding.ASCII.GetBytes(args[0].ToString());
break;
case 1:
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
toSend = ImageToByte(bitmap);
}
break;
}
if (toSend == null)
Console.WriteLine("what happened");
try
{
byte[] bufferedToSend = new byte[toSend.Length + 4];
byte[] lengthOfSend = BitConverter.GetBytes(toSend.Length);
Array.Copy(lengthOfSend, bufferedToSend, 4);
toSend.CopyTo(bufferedToSend, 4);
Console.WriteLine("Sending " + toSend.Length + " bytes" + " buffer len: "+bufferedToSend.Length);
serverStream.Write(bufferedToSend, 0, bufferedToSend.Length);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}