服务器接收字节消息或图像字节

Server receive Byte Message or Image bytes

下面我附上了我服务器中的一段代码。它是控制所有传入客户端消息的主要部分。有些消息只是字符串,而其他消息是图像。它有时会起作用,但有时 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);
        }
    }