当通过tcp c#接收图像时,随机获取参数异常和内存不足异常

本文关键字:异常 随机 获取 参数 内存不足 图像 tcp | 更新日期: 2023-09-27 18:14:27

我一直在绞尽脑汁想为什么会发生这种情况,它会运行几次很好,但它会随机接收长度为奇数(例如-123456,或者它会接收为0)。

然后当它要从流中生成图像时,它不能,因为长度错误。有时长度值看起来像一个正常的值,但当它去生成图像时,我仍然会得到参数异常。

编辑:我也随机接收"len"对象的大数,这会导致内存不足异常,但发送端从未发送任何与该数字一样大的东西,所以我不明白这个数字来自哪里。

接收代码:

    public void ReceiveSS()
    {
        bool firstTimeRun = true;
        TcpListener ssTcpListener = new TcpListener(IPAddress.Any, 63000);
        TcpClient tcpReceiver = new TcpClient();         
            ssTcpListener.Start();
            tcpReceiver = new TcpClient();
            if (!uPnPWorks)
            {
                try
                {
                    Console.WriteLine(contactIP + "      " + port);
                    tcpReceiver.Connect(contactIP.ToString(), port);
                }
                catch (Exception)
                {
                }
            }
            else
            {
                tcpReceiver = ssTcpListener.AcceptTcpClient();
            }
            while (!ssStop)
            {
                try
                {
                    //Start listening for connection.

                    if (tcpReceiver.Connected)
                    {
                        if (firstTimeRun)
                        {
                            //TCP connected. Receive images from contact.
                            NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client);
                            BinaryReader br = new BinaryReader(receivedNs);
                            byte[] lenOfImage = new byte[4];
                            br.Read(lenOfImage, 0, 4);
                            int len = (int)(lenOfImage[0] << 24) | (int)(lenOfImage[1] << 16) | (int)(lenOfImage[2] << 8) | lenOfImage[3];
                            Console.WriteLine(len);
                            byte[] receivedData = new byte[len];
                            br.Read(receivedData, 0, receivedData.Length);
                            MemoryStream ms = new MemoryStream(receivedData, 0, receivedData.Length);
                            ms.Seek(0, SeekOrigin.Begin);
                            receivedNs.Flush();
                            Bitmap image = new Bitmap(ms);
                            receivedImage = image;
                            //Put image into picturebox.
                            if (this.InvokeRequired)
                            {
                                this.Invoke(new MethodInvoker(delegate() { pboScreenShare.Image = image; }));
                            }
                            else { pboScreenShare.Image = image; }
                            //br.Close();
                            firstTimeRun = false;
                        }
                        else if (!firstTimeRun)
                        {
                            //TCP connected. Receive images from contact.
                            NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client);
                            BinaryReader br = new BinaryReader(receivedNs);
                            byte[] lenOfImage = new byte[4];
                            br.Read(lenOfImage, 0, 4);
                            int len = (int)(lenOfImage[0] << 24) | (int)(lenOfImage[1] << 16) | (int)(lenOfImage[2] << 8) | lenOfImage[3];
                            try
                            {
                                MemoryStream ms = new MemoryStream();
                                if (len > 0)
                                {
                                    byte[] receivedData = new byte[len];
                                    br.Read(receivedData, 0, receivedData.Length);
                                    ms = new MemoryStream(receivedData, 0, receivedData.Length);
                                    ms.Seek(0, SeekOrigin.Begin);
                                }
                                receivedNs.Flush();
                                receivedImage2 = new Bitmap(ms); //Where I get the random argument exception
                                receivedImage2.MakeTransparent(Color.Pink);
                                Bitmap overlayedImage = new Bitmap(receivedImage.Width, receivedImage.Height);
                                using (Graphics gr = Graphics.FromImage(overlayedImage))
                                {
                                    gr.DrawImage(receivedImage, new Point(0, 0));
                                    gr.DrawImage(receivedImage2, new Point(0, 0));
                                }
                                //Put image into picturebox.
                                this.Invoke(new MethodInvoker(delegate() { pboScreenShare.Image = overlayedImage; }));
                                receivedImage2.Dispose();
                                receivedImage = overlayedImage;
                                //br.Close();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message + "        Getting image");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString() + "     ReceiveSS()");
                }
            }
    }

发送代码:

private void SendSS()
    {
        int cursorX = 0;
        int cursorY = 0;
        TcpListener listener = new TcpListener(IPAddress.Any, 63001);
        listener.Start();
        tcpClient = new TcpClient();
        if (uPnPWorks)
        {
            tcpClient = listener.AcceptTcpClient();
        }
        else
        {
            try
            {
                tcpClient.Connect(contactIP, 63000);
            }
            catch (Exception)
            {
            }
        }
        bool firstTimeRun = true;
        while (!ssStop)
        {
            try
            {
                if (tcpClient.Connected)
                {
                    //Connected. Capture screen image.
                    if (firstTimeRun)
                    {
                        MemoryStream ssmemStream = new MemoryStream();
                        screenShotBMP = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
                        Bitmap cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
                        Graphics graphics = Graphics.FromImage(screenShotBMP as Image);
                        graphics.CopyFromScreen(0, 0, 0, 0, screenShotBMP.Size);
                        if (cursorBMP != null)
                        {
                            using (Graphics g = Graphics.FromImage(screenShotBMP))
                            {
                                Rectangle r = new Rectangle(cursorX, cursorY, cursorBMP.Width, cursorBMP.Height);
                                g.DrawImage(cursorBMP, r);
                            }
                        }
                        Bitmap saveScreenShot = screenShotBMP;
                        saveScreenShot.Save(ssmemStream, ImageFormat.Png);
                        NetworkStream ns = tcpClient.GetStream();
                        //Convert image to data.
                        BinaryWriter bw = new BinaryWriter(ns);
                        byte[] bytesToSend = ssmemStream.ToArray();
                        byte[] imageLen = new byte[4];
                        int len = bytesToSend.Length;
                        imageLen[0] = (byte)((len & 0xff000000) >> 24);
                        imageLen[1] = (byte)((len & 0x00ff0000) >> 16);
                        imageLen[2] = (byte)((len & 0x0000ff00) >> 8);
                        imageLen[3] = (byte)(len & 0xff);
                        ns.Write(imageLen, 0, 4);
                        ns.Write(bytesToSend, 0, bytesToSend.Length);
                        Console.WriteLine(bytesToSend.Length);
                        ns.Flush();
                        //bw.Close();
                        firstTimeRun = false;
                    }
                    else if (!firstTimeRun)
                    {
                        MemoryStream ssmemStream = new MemoryStream();
                        screenShotBMP2 = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
                        Bitmap cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
                        Graphics graphics = Graphics.FromImage(screenShotBMP2 as Image);
                        graphics.CopyFromScreen(0, 0, 0, 0, screenShotBMP2.Size);
                        if (cursorBMP != null)
                        {
                            using (Graphics g = Graphics.FromImage(screenShotBMP2))
                            {
                                Rectangle r = new Rectangle(cursorX, cursorY, cursorBMP.Width, cursorBMP.Height);
                                g.DrawImage(cursorBMP, r);
                            }
                        }
                        diffImage = ImageTool.GetDifferenceImage(screenShotBMP, screenShotBMP2, Color.Pink);
                        diffImage.Save(ssmemStream, ImageFormat.Png);
                        try
                        {
                            NetworkStream ns = tcpClient.GetStream();
                            //Convert image to data.
                            BinaryWriter bw = new BinaryWriter(ns);
                            byte[] bytesToSend = ssmemStream.ToArray();
                            byte[] imageLen = new byte[4];
                            int len = bytesToSend.Length;
                            Console.WriteLine(len);
                            imageLen[0] = (byte)((len & 0xff000000) >> 24);
                            imageLen[1] = (byte)((len & 0x00ff0000) >> 16);
                            imageLen[2] = (byte)((len & 0x0000ff00) >> 8);
                            imageLen[3] = (byte)(len & 0xff);
                            ns.Write(imageLen, 0, 4);
                            ns.Write(bytesToSend, 0, bytesToSend.Length);
                            Console.WriteLine(bytesToSend.Length);
                            ns.Flush();
                            //bw.Close();
                        }
                        catch
                        {
                            Console.WriteLine("iox exception");
                        }
                        screenShotBMP = screenShotBMP2;
                    }
                }
            }
            catch (SocketException sockEx)
            {
                Console.WriteLine(sockEx.Message + "        SendSS()");
            }
        }
    }

当通过tcp c#接收图像时,随机获取参数异常和内存不足异常

假设Read/Receive返回的恰好是您想要的数据量。事实并非如此。它最多返回那么多,并且至少返回一个字节。调整您的代码来处理这个事实。例如,通过使用BinaryReader或在循环中读取,直到获得所需的字节数。

更好:停止使用套接字。使用一些更高级的东西,比如HTTP或web服务。套接字在大多数情况下是错误的解决方案。