我创建了一个服务来接收来自特定客户端的数据。这工作正常,我收到我想要的大部分数据。但是在连接2-4小时后我在StreamReader.ReadLine上出现此错误,发生此错误后,服务开始占用cpu的90-99%,并且只能使用cmd和Taskkill关闭。
System.IO.IOException:无法从传输连接读取数据:远程主机强制关闭现有连接。 ---> System.Net.Sockets.SocketException:远程主机强制关闭现有连接 在System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags) 在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小) ---内部异常堆栈跟踪结束--- 在System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小) 在System.IO.StreamReader.ReadBuffer() 在System.IO.StreamReader.ReadLine()
连接代码:
static readonly object _lock = new object();
List<Task> _connections = new List<Task>();
private static string strConn;
private static int _port;
public async Task connectClients()
{
TcpListener ServerSocket = new TcpListener(IPAddress.Any, _port);
ServerSocket.Start();
while (true)
{
TcpClient client = await ServerSocket.AcceptTcpClientAsync();
var task = handle_clients(client);
if (task.IsFaulted)
task.Wait();
}
}
private async Task handle_clients(TcpClient client)
{
var connectionTask = HandleConnectionAsync(client);
lock (_lock)
_connections.Add(connectionTask);
try
{
await connectionTask;
}
catch (Exception ex)
{
new LogWriter(ex.ToString());
}
finally
{
// remove pending task
lock (_lock)
{
_connections.Remove(connectionTask);
client.GetStream().Close();
client.Close();
}
}
}
private async Task HandleConnectionAsync(TcpClient client)
{
await Task.Yield();
NetworkStream stream = client.GetStream();
StreamReader reader = new StreamReader(stream);
while (true)
{
try
{
string data = reader.ReadLine();
if (!string.IsNullOrWhiteSpace(data))
{
Thread t = new Thread(() => DatabaseFix(data));
t.Start();
}
}
catch (Exception ex)
{
new LogWriter(ex.ToString());
break;
}
}
}
因此,当连接因任何原因而关闭时,我预计会发生什么,它应该关闭连接,然后获得新连接?
这可能是客户端和服务之间的一些互联网错误“防火墙”吗?在这种情况下可能是什么错误?
答案 0 :(得分:0)
对于被捕的人。问题是客户端不断发送连接并再次关闭它们,直到它有任何数据要发送。当客户端连接出错时,我的代码没有关闭网络流。
将我的HandleConnectionAsync更改为此。
try
{
using (var stream = client.GetStream())
using (var reader = new StreamReader(stream))
{
while (true)
{
var data = await reader.ReadLineAsync();
if (string.IsNullOrEmpty(data))
{
break;
}
DatabaseFix(data);
}
}
}
catch (Exception ex)
{
new LogWriter(ex.ToString());
}