TCP数据包发送错误

发布于 2024-12-26 14:29:20 字数 1757 浏览 2 评论 0原文

我正在制作一个发送和接收小图像的网络摄像头应用程序。我已经使它能够发送和接收,我在 127.0.0.1 上进行了测试,效果很好,但现在我使用自己的外部 IP 地址,它似乎发送一张图像,接收一张图像,然后搞砸了,我明白了图像大小中存在某种巨大的整数值,一个负值会导致它崩溃,我认为接收和发送可能正在自行运行,并且以某种方式不同步。我在发送每张图像之前设置了 1000 毫秒的延迟,虽然速度很慢,但工作正常,一旦我取消延迟,它就会变得混乱。

这是代码:

    // This sends.
    private void NewFrameReceived(object sender, NewFrameEventArgs e)
    {
        Bitmap img = (Bitmap)e.Frame.Clone();

        byte[] imgBytes = EncodeToJpeg(img, 25).ToArray();
        if (_tcpOut.Connected)
        {
            NetworkStream ns = _tcpOut.GetStream();
            if (ns.CanWrite)
            {
                System.Threading.Thread.Sleep(500);
                ns.Write(BitConverter.GetBytes(imgBytes.Length), 0, 4);
                ns.Write(imgBytes, 0, imgBytes.Length);
            }
        }
    }

    // This receives.
    private void listeningThread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        // start listening for connections
        _tcpIn = new TcpListener(IPAddress.Any, 54321);
        _tcpIn.Start();

        TcpClient _inClient = _tcpIn.AcceptTcpClient();
        while (true)
        {
            NetworkStream ns = _inClient.GetStream();
            if (ns.CanRead && ns.DataAvailable)
            {
                Byte[] imgSizeBytes = new Byte[4];
                ns.Read(imgSizeBytes, 0, 4);
                int imgSize = BitConverter.ToInt32(imgSizeBytes, 0);

                Byte[] imgBytes = new Byte[imgSize];  <-- ERROR, GET CRAZY LARGE VALUE
                ns.Read(imgBytes, 0, imgSize);

                MemoryStream ms = new MemoryStream(imgBytes);
                Image img = Image.FromStream(ms);

                picVideo.Image = img;
            }
        }
    }

I'm making a webcam app that sends and receives small images. I have made it be able to send and receive, I tested on 127.0.0.1 and it worked fine, but now I'm using my own external IP address and it seems to send one image, receive one, then mess up, I get some sort of massive integer value in the image size, a minus value which leads it to crash, I think maybe the receive and send are running on their own, and are going out of sync somehow. I put a 1000ms delay before sending out each image and it was slow but working, as soon as I take the delay out, it messes up.

Here is the code :

    // This sends.
    private void NewFrameReceived(object sender, NewFrameEventArgs e)
    {
        Bitmap img = (Bitmap)e.Frame.Clone();

        byte[] imgBytes = EncodeToJpeg(img, 25).ToArray();
        if (_tcpOut.Connected)
        {
            NetworkStream ns = _tcpOut.GetStream();
            if (ns.CanWrite)
            {
                System.Threading.Thread.Sleep(500);
                ns.Write(BitConverter.GetBytes(imgBytes.Length), 0, 4);
                ns.Write(imgBytes, 0, imgBytes.Length);
            }
        }
    }

    // This receives.
    private void listeningThread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        // start listening for connections
        _tcpIn = new TcpListener(IPAddress.Any, 54321);
        _tcpIn.Start();

        TcpClient _inClient = _tcpIn.AcceptTcpClient();
        while (true)
        {
            NetworkStream ns = _inClient.GetStream();
            if (ns.CanRead && ns.DataAvailable)
            {
                Byte[] imgSizeBytes = new Byte[4];
                ns.Read(imgSizeBytes, 0, 4);
                int imgSize = BitConverter.ToInt32(imgSizeBytes, 0);

                Byte[] imgBytes = new Byte[imgSize];  <-- ERROR, GET CRAZY LARGE VALUE
                ns.Read(imgBytes, 0, imgSize);

                MemoryStream ms = new MemoryStream(imgBytes);
                Image img = Image.FromStream(ms);

                picVideo.Image = img;
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

话少心凉 2025-01-02 14:29:20

你需要重新考虑一下......数据可能以不同的数据包到达。您的读取功能只会读取可用的内容。这将导致您的系统不同步。

我会为图像构建一个小协议,这样我就可以随时知道图像在数据流中的开始和结束位置。

你不必这样做,但它让生活变得更容易,你可以纯粹通过一个简单的状态机来完成它,它知道接收图像已经走了多远。但是发送图像时的任何不合规性(例如流中的 1 个额外字节)都可能导致图像永远不同步。

you need to rethink things a little bit..... the data could arrive in different packets. Your read function will only read what is available. This will lead your system to get out of synch.

I'd build a little protocol for images so I can always tell where the start and end of images are in my data stream.

you don't HAVE to do that, but it makes life easier, you could do it purely by a simple state machine that knows how far through receiving an image it has got. But any non compliance in sending the image ( 1 extra byte in the stream for example) could send the thing out of synch forever.

往事随风而去 2025-01-02 14:29:20

Read 不一定读取您要求的那么多字节,只是当前可用的字节数一样 - 您实际上应该检查返回值以了解它读取了多少字节。 文档可能会帮助您更好的理解。

您应该添加逻辑以继续读取,直到读取所有图像字节。伪代码示例:

total_bytes_read = 0;
while (total_bytes_read != total_bytes_needed)
{
    bytes_left_to_read = total_bytes_needed - total_bytes_read;
    total_bytes_read += read(buffer, total_bytes_read, bytes_left_to_read);
}

Read doesn't necessarily read as many bytes as you ask for, just as many happen to be currently available -- you should actually check the return value to see how many it read. The documentation might help give you a better understanding.

You should add logic to keep reading until all of the image bytes have been read. A pseudo-code example:

total_bytes_read = 0;
while (total_bytes_read != total_bytes_needed)
{
    bytes_left_to_read = total_bytes_needed - total_bytes_read;
    total_bytes_read += read(buffer, total_bytes_read, bytes_left_to_read);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文