服务器接收字节消息或图像字节
本文关键字:字节 图像 消息 服务器 | 更新日期: 2023-09-27 18:37:06
下面我附加了一段我在服务器中的代码。它是控制所有传入客户端消息的主要段。有些消息只是字符串,而其他消息是图像。它有时有效,但有时 while 循环(将标记)将在整个图像完成之前中断。
我不确定是否有更好的方法来检测正在发送的内容,因为目前我只是寻找关键字以查看它是否是图像。
主要问题不是如何检测传入的字节是否是图像,因为搜索PNG等单词似乎不是问题......主要问题是下面指示的 while 循环的过成熟中断
我还注意到,由于某种原因,while 循环在我的笔记本电脑而不是台式机上正常运行。可能是一个麻烦,但我不确定这个说法是否有用。
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;
}
});
}
}
这里有一些更新的代码,适用于那些需要理解它的人。
服务器端:
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;
}
});
}
}
客户端:
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);
}
}