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

时间:2014-07-23 12:24:44

标签: c# image tcp argumentexception

我一直在思考为什么会发生这种情况,它会很好地运行几次,但它会随机收到一个奇数的长度(例如-123456,或者它&& #39;将收到0)。

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

编辑:我也随机收到" len"导致Out Of Memory Exception的对象,但发送方从不发送任何与该数字一样大的内容,因此我不明白该数字的来源。

这是接收代码:

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

1 个答案:

答案 0 :(得分:1)

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

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