从网络流异步读取时出错

本文关键字:出错 读取 异步 网络 | 更新日期: 2023-09-27 18:14:54

我做了一个应用程序与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); }
    }

从网络流异步读取时出错

首先,众所周知,网络流上的异步方法会丢失数据或永远不会返回数据!在你的情况下,它可能是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方法。