C#WinForms(TcpClient) - 无法从/向传输连接读/写数据:远程主机强制关闭现有连接

时间:2012-03-09 10:28:52

标签: c# winforms network-programming asterisk tcpclient

我意识到有很多关于这方面的文章,但我很难找到解决这个具体问题的方法。

服务器是Asterisk PBX服务器,它不断地将呼叫数据写入套接字。

目前大约有10个客户端连接到服务器,这些客户端随机无法读取/写入传输连接异常。这可能是在程序加载时的第一次读/写或4小时后。此问题没有一致性或模式。客户不会在同一时间但在不同时间收到所有这些内容。

有人知道为什么会这样吗?另外,因为我对网络编程很不满意,当捕获到这个异常时,将tcp客户端重新连接到服务器的最佳和最优雅的方法是什么?

提前谢谢。

    private TcpClient client;
    private NetworkStream stream;
    private Encoding encoding;

    private void frmMain_Load(object sender, EventArgs e)
    {   
        this.client = new TcpClient("192.168.0.100", 5038);
        this.stream = this.client.GetStream();
        this.encoding = Encoding.ASCII;

        if (client.Connected)
            BeginRead();
    }

    private void BeginRead()
    {
        try
        {
            NetworkStream stream = this.client.GetStream();
            byte[] buffer = new byte[client.ReceiveBufferSize];
            IAsyncResult ar = stream.BeginRead(buffer, 0, buffer.Length, OnReadComplete, buffer);
        }
        catch (IOException ioex)
        {
            //Unable to read data from the transport connection caught here.
            //How to reconnect gracefully?
        }
        catch (Exception ex)
        {
            //Handle...
        }
    }

    private void OnReadComplete(IAsyncResult ar)
    {
        try
        {
            NetworkStream stream = this.client.GetStream();
            byte[] buffer = (byte[])ar.AsyncState;
            int bytesRead = stream.EndRead(ar);

            if (bytesRead > 0)
            {
                //Process response here...
            }

            BeginRead();  //Read again after read completed
        }
        catch (Exception ex)
        {
            //Handle...
        }
    }

    private void BeginWrite(string msg)
    {
        try
        {
            byte[] data = encoding.GetBytes(msg);
            IAsyncResult ar = stream.BeginWrite(data, 0, data.Length, this.OnWriteComplete, stream);
            stream.Flush();
        }
        catch (IOException ioex)
        {
            //Unable to write data to the transport connection caught here.
            //How to reconnect gracefully?
        }
        catch (Exception ex)
        {
            //Handle...
        }
    }

    private void OnWriteComplete(IAsyncResult ar)
    {
        try
        {
            NetworkStream arStream = (NetworkStream)ar.AsyncState;
            arStream.EndWrite(ar);
        }
        catch (Exception ex)
        {
            //Handle...
        }
    }

1 个答案:

答案 0 :(得分:0)

我怀疑这是因为你忘了“关闭”'NetworkStream'对象。如果你不这样做,GC会。但是,当GC收集'NetworkStream'时,对象不是确定性的,这就是你看到这种随机行为的原因。