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

时间:2015-01-10 17:50:31

标签: c# sockets networking tcpclient

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

1 个答案:

答案 0 :(得分:1)

以下是一些适用于需要了解它的人的更新代码。

服务器端:

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);
        }
    }