【问题标题】:Error in asynchronous read from the NetworkStream从 NetworkStream 异步读取时出错
【发布时间】:2011-12-29 08:51:05
【问题描述】:

我制作了一个与 IP 摄像机通信的应用程序。这被配置为在预定义的地址上建立连接。 TCP 侦听器正在该地址上运行并接受来自摄像头的连接。当相机连接时,我发送命令以从相机获取 MJpeg 流,相机开始发送流以响应命令。

我正在使用异步方法从套接字读取流。但是一段时间后,我的应用程序在从网络流中读取数据时卡住了。

我正在使用此代码从网络流中读取数据,并且我在屏幕上写了一些消息以获取相机连接的状态。

    private void ReadData()
    {
        try
        {
            string msg = "Reading Data... client connected " + _camClient.Connected.ToString() +
                         "... netStream Readable " +
                         _netStream.CanRead.ToString();
            Console.WriteLine(msg);

            _callback = new AsyncCallback(GetData);
            _buffer = new byte[Buffersize];
            _async = _netStream.BeginRead(_buffer, 0, Buffersize, _callback, null);
        }
        catch (Exception ex) { Console.WriteLine("ReadData: " + ex.Message); }
    }

    private void GetData(IAsyncResult result)
    {
        try
        {
            int read = _netStream.EndRead(result);
            if (read > 0)
            {
                _data = new byte[read];
                Array.Copy(_buffer, 0, _data, 0, read);
                ProcessData();
            }
            ReadData();
        }
        catch (Exception ex) { Console.WriteLine("GetData: " + ex.Message); }
    }

【问题讨论】:

  • 卡住时最后写入的消息是什么?
  • 我看到最后一条消息是“正在读取数据...客户端已连接为真...netStream 可读为真”。此消息应用程序卡住后。

标签: c# network-programming tcplistener


【解决方案1】:

首先,网络流上的异步方法以丢失数据或从不返回数据而闻名! 在您的情况下,可能是 ProcessData 调用被阻塞。

您应该做的是使用阻塞侦听器(非异步)生成一个新的后台线程,然后在侦听器继续侦听时使用新线程读取数据。 我这里有一个例子。

private static Socket s_chatListener;
public static void Listen(IPAddress LocalIPAddress, int Port)
    {
            IPEndPoint ipend = new IPEndPoint(LocalIPAddress, Port);
            s_chatListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s_chatListener.Bind(ipend);
            s_chatListener.Listen(10);


            while (true)
            {
                Socket handler = s_chatListener.Accept();

                ParameterizedThreadStart pst = new ParameterizedThreadStart(loadMessageFromSocket);
                Thread t = new Thread(pst);
                t.Start(handler);


            }
    }


 private static  void loadMessageFromSocket(object socket)
    {
        Socket handler = (Socket)socket;
        string data = "";
        while (true)
        {
            byte[] butes = new byte[1024];
            int rec = handler.Receive(butes);

            data += ASCIIEncoding.ASCII.GetString(butes);

            if (data.IndexOf("\0") > -1)
                break;
        }

        handler.Shutdown(SocketShutdown.Both);
        handler.Close();


        Console.Write(data);
    }

现在只需从主窗体或调用者类中的新线程调用 Listen 方法。 希望这会有所帮助。

【讨论】:

  • 嗨,詹姆斯·詹金斯!在我们的场景中,我们的客户端是一个 IP 摄像头,因此我们正在获取流以响应我们发送到摄像头的命令,并且摄像头开始无限发送 Mjpeg 流,那么我如何在我们的场景中使用此代码。
  • 不要使用异步。启动一个新线程,将命令发送到 IP Camera 然后读取流,您可以使用 StreamReader。然后,当您将图像设置为通知调用者的事件时。
  • 詹姆斯我们不知道图像的数量,相机开始发送流,当我们最终接收到数据时,我们从流中获取图像。
  • 相机开始以这种方式发送流,我们在我们的应用程序中分离图像 "Content-Type: multipart/x-mixed-replace; boundary=--myboundary..." "...-- myboundary.Content-type: image/jpeg..." JPEG 二进制数据 No. 1 (Hexadecimal notation="FFD8............. .......FFD9") "...--myboundary.Content-type: image/jpeg..." JPEG 二进制数据 No. 2 (Hexadecimal notation="FFD8......... .......................FFD9") : : "...--myboundary.Content-type: image/jpeg..." JPEG 二进制数据编号 N(十六进制表示法="FFD8.................................FFD9")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
相关资源
最近更新 更多