异步TCP读取时发生Stackoverflow
本文关键字:Stackoverflow TCP 读取 异步 | 更新日期: 2023-09-27 18:10:14
最后一个适合这个网站的问题。
我有一个。net TCP服务器。这是我的第一个服务器,它工作得很好。客户端的加入,被管理,可以加入聊天室等。然而,大约30分钟后,在建立了一个客户端后,我得到了一个系统。在NetworkStream.ReadAsync期间发生StackOverflowException。我完全不知道这是什么问题。这是常事。
下面是关于我的TCP服务器的Client类的重要细节,当一个客户端加入时,一个新的Client被创建。
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 void StartReadAsync(){
ReadAsync(cts.Token);
}
private async Task ReadAsync(CancellationToken ct) {
// Stackoverflow exception occurs on next line after 20-30 mins
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();
}
}
ReadAsync(ct);
}
}
你正在做一个可重入调用,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; }
}
}