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

C# 通过tcp c接收图像时随机获取参数异常和内存不足异常#,c#,image,tcp,argumentexception,C#,Image,Tcp,Argumentexception,我一直在绞尽脑汁想为什么会发生这种情况,它会运行好几次,但它会随机地以奇数形式接收长度(-123456,例如,它会以0形式接收) 然后,当它从流中生成图像时,它不能,因为长度是错误的。有时,长度值看起来像正常值,但在生成图像时,我仍然会得到参数异常 编辑:我还随机接收到“len”对象的大数字,这会导致内存不足异常,但发送端从未发送过如此大的数字,因此我不知道该数字来自何处 这是接收代码: public void ReceiveSS() { bool firstTi

我一直在绞尽脑汁想为什么会发生这种情况,它会运行好几次,但它会随机地以奇数形式接收长度(-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()");
                }
            }
    }

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


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

您好,我使用的是BinaryReader,它仍然没有返回适当的数量。我将尝试你提到的循环阅读。而使用http services.BinaryReader.Read只是将调用中继到底层流。不过,ReadBytes会读取您想要的字节数(如果可用)。谢谢,BinaryRead.ReadBytes工作得非常好!我会投票支持你,但我的名声太低了(
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()");
            }
        }
    }