异步TCP读取期间的Stackoverflow

时间:2015-08-28 23:21:28

标签: c# tcp

这个网站最终是一个合适的问题。

我有一台.NET TCP服务器。这是我的第一台服务器,它运行良好。客户端加入,管理,可以加入聊天室等。但是,大约30分钟后,在建立一个客户端后,我在NetworkStream.ReadAsync期间收到System.StackOverflowException。我完全不知道问题是什么。它每次都会发生。

以下是有关我的TCP服务器客户端类的重要详细信息,其中在客户端加入时创建了新客户端。

<table id="example" class="display" width="100%" data-page-length="25">
    <thead>
        <tr>
            <th>Name</th>
            <th data-orderable="false">Avatar</th>
            <th>Start date</th>
            <th>Salary</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Tiger Nixon</td>
            <td><img src="https://www.gravatar.com/avatar/8edcff60cdcca2ad650758fa524d4990?s=64&amp;d=identicon&amp;r=PG" alt="" style="width: 64px; height: 64px; visibility: visible;"></td>
            <td>2011/04/25</td>
            <td>$320,800</td>
        </tr>
        <tr>
            <td>Garrett Winters</td>
            <td><img src="https://www.gravatar.com/avatar/98fe9834dcca2ad650758fa524d4990?s=64&amp;d=identicon&amp;r=PG" alt="" style="width: 64px; height: 64px; visibility: visible;"></td>
            <td>2011/07/25</td>
            <td>$170,750</td>
        </tr>
        ...[ETC]...
    </tbody>
</table>

1 个答案:

答案 0 :(得分:2)

您正在进行重入调用,ReadAsync再次调用ReadAsync,所以是的,您将结束StackOverflow异常。

将您的代码更改为:

public class Client 
{

    public TcpClient tcpClient;

    public NetworkStream stream;

    public CancellationTokenSource cts = new CancellationTokenSource();

    private byte[] readBuffer = new byte[1024];

    private StringBuilder receiveString = new StringBuilder();


    public Client(TcpClient tcpClient) {
        this.tcpClient = tcpClient;
        this.stream = this.tcpClient.GetStream();
    }

    public async void StartReadAsync(){

        while(await ReadAsync(cts.Token));
    }

    private async Task<bool> ReadAsync(CancellationToken ct) 
    {

        try
        {
            int amountRead = await stream.ReadAsync(readBuffer, 0, readBuffer.Length, ct);
            if (amountRead > 0)
            {
                string message = Encoding.UTF8.GetString(readBuffer, 0, amountRead);
                receiveString.Append(message);
                Console.WriteLine("Client " + name + " sent: " + message);

                if (receiveString.ToString().IndexOf(eof) > -1)
                {
                    // Full message received, otherwise keep reading
                    if (OnClientRead != null)
                        OnClientRead(this, new SocketEventArgs(this, receiveString.ToString()));
                    receiveString.Clear();
                }

                return true;
            }

            return false;
        }
        catch { return false; }

    }
}